Applying .NET Remoting

Team-Fly    

Developing XML Web Services and Server Components with Visual C#™ .NET and the .NET Framework, Exam Cram™ 2 (Exam 70-320)
By Amit Kalani, Priti Kalani

Table of Contents
Chapter 4.  .NET Remoting


The exam does not require you to write code. However, the questions might require you to understand code segments for performing various remoting tasks. In particular, you should know how to create a remotable class and how to create server-activated and client-activated objects from the class.

Creating a Remotable Class

Creating a remotable class is simple. All you need to do is inherit a class from the MarshalByRefObject class or any of its derived classes. The following example creates a remotable class named DbConnect. This class connects to a specified SQL Server database and enables you to execute a SELECT SQL statement by using its ExecuteQuery() method. To create a remotable class, follow these steps:

  1. Launch Visual Studio .NET. Create a new blank solution named (C04) at C:\EC70320.

  2. Add a new Visual C# .NET class library project (Example4_1) to the solution. Rename the default Class1.cs to DbConnect.cs.

  3. Replace the code for DbConnect.cs with the following:

     using System; using System.Data; using System.Data.SqlClient; namespace Example4_1 {     public class DbConnect : MarshalByRefObject     {         private SqlConnection sqlconn;         // connect to the Northwind database         public DbConnect() : this("Northwind") { }         // connect to the specified database         public DbConnect(string DbName)         {             sqlconn = new SqlConnection(@"data source=(local)\NetSDK;" +                 @"initial catalog=" + DbName + @";integrated security =SSPI");             Console.WriteLine("Created a new connection " +                 "to the {0} database.", DbName);         }         public DataSet ExecuteQuery(string strQuery)         {             Console.Write("Starting to execute the query...");             SqlDataAdapter sqlda = new SqlDataAdapter(strQuery, sqlconn) ;             DataSet ds = new DataSet();             try {                 sqlda.Fill(ds, "Results");             }             catch (Exception ex)  {                Console.WriteLine(ex.Message, "Error executing query");             }             Console.WriteLine("Done.");             return ds;         }     } } 
  4. Build the project. This step packages the remotable class into the file Example4_1.dll, which is located in the bin\Debug directory of your project.

Creating a Server-Activated Object

A remotable class is usually connected with the remoting framework through a separate server program. To create such a program, you need to take the following steps:

  1. Create a server channel that listens on a particular port to the incoming object-activation requests from other application domains. For example:

     // Register a TCP server channel on port 1234 TcpServerChannel channel = new TcpServerChannel(1234); // Register an HTTP server channel on port 1235 HttpServerChannel channel = new HttpServerChannel(1235); 
  2. Register the channel with the remoting framework. For example:

     // Register the channel with the remoting framework ChannelServices.RegisterChannel(channel); 
  3. Register the remotable class with the remoting framework. For example:

     //Register a remote object with the remoting framework RemotingConfiguration.RegisterWellKnownServiceType(     typeof(DbConnect),  // type of the remotable class     "DbConnect",      // URI of the remotable class     WellKnownObjectMode.SingleCall //Activation mode ); 

graphics/alert_icon.gif

The channel registration and the remote object registration are not related. In fact, a remote object can be accessed through all registered channels.


Windows service applications such as Internet Information Services (IIS) continuously run in the background and therefore provide an ideal mechanism for hosting remote objects. However, you can also use a simple Windows form or console application for hosting remote objects.

Using the SingleCall Activation Mode to Register a Remotable Class As a Server-Activated Object

Follow these steps to create a server that exposes the DbConnect class as a SingleCall SAO:

  1. Add a new Visual C# .NET console application named Example4_2 to the solution.

  2. Add references to the .NET assembly System.Runtime.Remoting and the project Example4_1.

  3. In the Solution Explorer, rename the default Class1.cs to DbConnectSingleCallServer.cs. Open the file and change the name of the class to DbConnectSingleCallServer in the class declaration.

  4. Add the following using directives to the code:

     using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; 
  5. Add the following code in the Main() method:

      [STAThread] static void Main(string[] args) {     // Create and register a TCP server channel that listens on port 1234     TcpServerChannel channel = new TcpServerChannel(1234);     ChannelServices.RegisterChannel(channel);     // Register the service that publishes     // DbConnect for remote access in SingleCall mode     RemotingConfiguration.RegisterWellKnownServiceType         (typeof(Example4_1.DbConnect), "DbConnect",         WellKnownObjectMode.SingleCall);     Console.WriteLine("Started server in the SingleCall mode");     Console.WriteLine("Press <ENTER> to terminate server...");     Console.ReadLine(); } 
  6. Build the project. This step creates a server that registers a class with the remoting framework for remote invocation by using the SingleCall activation mode via a TCP channel.

Instantiating and Invoking a Server-Activated Object

You need to take the following steps to create a client that sends messages to the server to activate the remote object:

  1. Create and register a client channel that is compatible with the channel used by server.

  2. Register the remotable class as a valid type in the client's application domain.

  3. Instantiate the SAO on the server.

graphics/alert_icon.gif

You can instantiate an SAO at the client side only, by using its default constructor.


Follow these steps to create a remoting client that instantiates and invokes a server-activated object:

  1. Add a new Visual C# .NET Windows application named Example4_3 to the solution.

  2. Add references to the .NET assembly System.Runtime.Remoting and the project Example4_1 (the remotable class assembly).

  3. Place a TextBox control (txtQuery, with its MultiLine property set to true), a Button control (btnExecute), and a DataGrid control (dgResults) on the form.

  4. Add the following using directives to the form's code:

     using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; using Example4_1; 
  5. Add the following code in the class definition:

     // Declare a Remote object DbConnect dbc; 
  6. Double-click the form and add the following code in the Load event handler:

     private void Form1_Load(object sender, System.EventArgs e) {     // Step 1: Register a TCP client channel     TcpClientChannel channel = new TcpClientChannel();     ChannelServices.RegisterChannel(channel);     // Step 2: Register the remote class as a valid     // type in the client's application domain     RemotingConfiguration.RegisterWellKnownClientType(         typeof(DbConnect),                 // Remote class         "tcp://localhost:1234/DbConnect"); // URL of the remote class     // Step 3: Instantiate the remote class     dbc = new DbConnect(); } 
  7. Double-click the Button control and add the following code in the Click event handler:

     private void btnExecute_Click(object sender, System.EventArgs e) {     try {       // Invoke a method on the remote object       this.dgResults.DataSource = dbc.ExecuteQuery(this.txtQuery.Text);       dgResults.DataMember = "Results";     }     catch(Exception ex)     {         MessageBox.Show(ex.Message, "Query Execution Error");     } } 
  8. Build the project. Start Windows explorer and start the server program (Example4_2), followed by the client program (Example4_3). Enter a query in the text box and click the Execute Query button. The client invokes a method on the remote object and binds the results from the remote method to the DataGrid control.

Using the Singleton Activation Mode to Register a Remotable Class As a Server-Activated Object

To create a server that exposes the DbConnect class as a Singleton SAO, you use the following code segment:

 // Resgister the service that publishes DbConnect in Singleton mode RemotingConfiguration.RegisterWellKnownServiceType(          typeof(Example4_1.DbConnect), "DbConnect",          WellKnownObjectMode.Singleton); 

Creating a Client-Activated Object

When exposing a remotable class as a CAO, no changes are required to be made on the remotable class. Instead, only the server and client differ on how the remotable class is registered with the remoting system.

Registering a Remotable Class As a Client-Activated Object

You need to take the following steps to register a remotable class as a CAO on the server:

  1. Create a server channel that listens on a particular port to the incoming object-activation requests from other application domains. The following examples show how to create a TCP server channel and an HTTP server channel:

     // Register a TCP server channel on port 1234 TcpServerChannel channel = new TcpServerChannel(1234); // Register an HTTP server channel on port 1235 HttpServerChannel channel = new HttpServerChannel(1235); 
  2. Register the channel with the remoting framework. This registration is performed through the RegisterChannel() method of the ChannelServices class:

     // Register the channel with the remoting framework ChannelServices.RegisterChannel(channel); 
  3. Register the remotable class with the remoting framework. For a client-activated object, use the RegisterActivatedServiceType() method of the RemotingConfiguration class to perform the registration, as shown here:

     // Register a remote object as a CAO with the remoting framework RemotingConfiguration.RegisterActivatedServiceType(typeof(DbConnect)) ; 
Instantiating and Invoking a Client-Activated Object

To instantiate and invoke a client-activated object, the remoting client needs to take the following steps:

  1. Create and register a client channel that the remoting framework uses to send messages to the remoting server. The type of channel the client uses should be compatible with the channel the server uses. The following examples show how to create a TCP client channel and an HTTP client channel:

     // Create and register a TCP client channel TcpClientChannel channel = new TcpClientChannel(); ChannelServices.RegisterChannel(channel); // Create and register an HTTP client channel HttpClientChannel channel = new HttpClientChannel(); ChannelServices.RegisterChannel(channel); 
  2. Register the remotable class as a valid type in the client's application domain. This registration is performed using the RegisterActivatedClientType() method of the RemotingConfiguration class, as shown here:

     // Register DbConnect as a type on client, // which can be activated on the server RemotingConfiguration.RegisterActivatedClientType       (typeof(DbConnect), "tcp://localhost:1234"); 

    In this code, the first parameter is the type of the remotable class. The second parameter specifies the uniform resource identifier (URI) through which the server publishes the location of the remote object.

  3. Instantiate the CAO on the server by using the desired constructor.

     // Instantiate the remote object DbConnect dbc = new DbConnect("Pubs"); 

graphics/alert_icon.gif

You can instantiate a CAO on the client side by using any of its available constructors.


Using Configuration Files to Configure the Remoting Framework

In all the examples written so far, I have written code to register the channel and the remote object with the remoting framework. This approach of specifying settings is also known as programmatic configuration. Alternatively, you can store the remoting settings in an XML-based configuration file. Any changes made to the configuration file can be automatically picked up by the program when it executes the next time. This approach of specifying configuration settings is also known as declarative configuration.

The declarative configuration can be specified at two levels:

  • Machine level This works through the machine.config file, which is present in the CONFIG subdirectory of the .NET Framework installation directory. Any settings specified in this file apply to all the .NET applications running on the machine.

  • Application level In a Windows application, the name of the application level configuration file includes the full application name and the extension, with .config appended to the extension. For example, the configuration filename for Example4_3.exe is Example4_3.exe.config. In an ASP.NET application, the name of the configuration file is web.config.

graphics/alert_icon.gif

When you specify both application-level configuration and machine-level configuration for an application, the application-level configuration takes priority over the machine-level configuration.


The general format of the configuration file is as follows (note that the configuration files are case sensitive):

 <configuration>  <system.runtime.remoting>   <application>     <lifetime>       <!-- Use this section to specify the lifetime information -->       <!-- for all the objects in the application. -->     </lifetime>     <service>       <!-- Use this section to specify how a remote-->       <!-- object is exposed by the remoting server-->       <!-- Use the <wellknown> tag to configure an SAO -->       <!-- and use the <activated> tag to configure a CAO -->       <wellknown />       <activated />     </service>     <client>       <!-- Use this section to specify how a remote object is consumed        Use the <wellknown> tag to configure a call to the SAO and        use the <activated> tag to configure a call to the CAO -->       <wellknown />       <activated />     </client>     <channels>       <!-- Use this section to configure the channels that the -->       <!-- application uses to communicate with the remote objects -->     </channels>   </application> </system.runtime.remoting> </configuration> 
Server-Side Configuration

Follow these steps to learn how to use configuration files to create a server that registers a remotable class as a client-activated object:

  1. Add a new Visual C# .NET console application named Example4_4 to the solution.

  2. Add references to the .NET assembly System.Runtime.Remoting and the project Example4_1.

  3. Add a new application configuration file (App.config) to the project, and modify it to contain the following code:

     <?xml version="1.0" encoding="utf-8" ?> <configuration>   <system.runtime.remoting>     <application>       <service>         <!-- Set the remotable object -->         <activated type= "Example4_1.DbConnect, Example4_1" />       </service>       <channels>           <!-- Set the channel and port -->           <channel ref="tcp" port="1234" />       </channels>    </application>  </system.runtime.remoting> </configuration> 
  4. In the Solution Explorer, rename the default Class1.cs to DbConnectCAOServer.cs. Open the file and change the name of the class to DbConnectCAOServer in the class declaration.

  5. Add the following using directive:

     using System.Runtime.Remoting; 
  6. Add the following code in the Main() method:

     [STAThread] static void Main(string[] args) {     RemotingConfiguration.Configure("Example4_4.exe.config");     Console.WriteLine("Started server in the client activation mode");     Console.WriteLine("Press <ENTER> to terminate the server...");     Console.ReadLine(); } 
  7. Build the project. This step creates a remoting server that registers the Example4_1.DbConnect class for remote invocation by using the client-activation mode via its settings in the configuration file.

For ease in development, when Visual Studio .NET builds a project, it automatically creates the .exe.config file from the contents of the App.config file.

The Configure() method of the RemotingConfiguration class loads the configuration file into memory, parses its contents to locate the <system.runtime.remoting> section, and, based on the settings, calls the relevant methods to register the channels and the remoting objects.

Client-Side Configuration

The configuration of the remoting client is quite similar to that of the remoting server. However, you configure the <client> element of the configuration file instead of the <service> element. Follow these steps to learn how to use the client-side configuration files for invoking a client-activated object.

  1. Add a new Visual C# .NET Windows application named Example4_5 to the solution.

  2. Add references to the .NET assembly System.Runtime.Remoting and the project Example4_1.

  3. Add a new application-configuration file (App.config), and modify it to contain the following code:

     <?xml version="1.0" encoding="utf-8" ?> <configuration>     <system.runtime.remoting>         <application>             <client url="tcp://localhost:1234" >                 <activated type= "Example4_1.DbConnect, Example4_1"             </client>         </application>     </system.runtime.remoting> </configuration> 
  4. Place a ComboBox control (cboDatabases), a Button control (btnSelect), a TextBox control (txtQuery, with its MultiLine property set to true), a Button control (btnExecute), and a DataGrid control (dgResults) on the form.

  5. Add the following database names to the Items property of the cboDatabases control:

     Northwind Pubs GrocerToGo 
  6. Add the following using directives:

     using System.Runtime.Remoting; using Example4_1; 
  7. Add the following code in the class definition:

     // Declare a Remote object DbConnect dbc; 
  8. Double-click the form and add the following code in the Load event handler:

     private void Form1_Load(object sender, System.EventArgs e) {    RemotingConfiguration.Configure("Example4_5.exe.config");    txtQuery.Enabled = false;    btnExecute.Enabled = false; } 
  9. Add the following code to the Click event handler of the btnSelect control:

     private void btnSelect_Click(object sender, System.EventArgs e) {     dbc = new DbConnect(cboDatabases.SelectedItem.ToString());     cboDatabases.Enabled = false;     btnSelect.Enabled = true;     txtQuery.Enabled = true;     btnExecute.Enabled = true; } 
  10. Add the following code in the Click event handler of the btnExecute control:

     private void btnExecute_Click(object sender, System.EventArgs e) {     try {         this.dgResults.DataSource = dbc.ExecuteQuery(txtQuery.Text);         dgResults.DataMember = "Results";     }     catch(Exception ex)     {         MessageBox.Show(ex.Message, "Query Execution Error");     } } 
  11. Build the project. Run the remoting server (Example4_4.exe) and then multiple instances of the client program (Example4_5.exe). You will be able to connect to a different database through each client program.

Unlike the server-configuration file, the <channel> element is not required for the client because the client uses the URL to determine the protocol and the port number.

Using IIS As an Activation Agent

Using IIS as an activation agent offers the following advantages:

  • You need not write a separate server program to register the remotable classes.

  • You need not worry about finding an available port for your server application. You can just host the remotable object, and IIS automatically uses port 80.

  • IIS can provide other functionality, such as authentication and Secure Socket Layers (SSL).

graphics/alert_icon.gif

.NET remoting has no built-in support for security. Instead, it depends on the remoting hosts to provide security. The only built-in remoting host that provides security for remote objects is IIS. Therefore, any secured objects must be hosted in IIS.


The following list specifies what you need to do to host a remotable class in IIS:

  • Place the assembly containing the remotable objects in the \bin directory of an IIS Web application, or place the assembly in the Global Assembly Cache (GAC).

  • Configure the remoting settings by placing the <system.runtime.remoting> configuration section in the web.config file for the Web application. Alternatively, you can write the configuration code in the Application_Start() event handler of the global.asax file in the same way you would register a remote object in an .exe host.

  • You should not specify a channel. IIS already listens on port 80. Specifying a port for a channel causes exceptions to be thrown when new IIS worker processes are started.

  • The well-known object URIs must end with .rem or .soap because these are the two extensions that are registered with both IIS (via aspnet_isapi.dll) and the remoting system (in machine.config).

graphics/alert_icon.gif

When creating IIS-hosted remote objects, you cannot specify constructor parameters; therefore, it is not possible to use IIS to activate CAO.


graphics/alert_icon.gif

IIS activation supports only the HTTP channel. The default formatting is SOAP, but IIS also supports binary and custom formatting.


Follow these steps to use IIS for activating the DbConnect remotable class:

  1. Add a new empty Web project named Example4_6 to the solution. Add a reference to project Example4_1.

  2. Add a Web configuration file (Web.config) to the project and add the following <system.runtime.remoting> element inside the <configuration> element:

     <configuration>   <system.runtime.remoting>     <application>        <service>         <!-- Set the activation mode, remotable object, and its URL -->         <wellknown mode="Singleton"                type="Example4_1.DbConnect, Example4_1"                objectUri="DbConnect.rem"/>       </service>      </application>     </system.runtime.remoting> ... </configuration> 
  3. IIS is now hosting the Example4_1.DbConnect remotable class as a server-activated object by using the Singleton activation mode.

Take the following steps to create a client program that invokes a remote object hosted in IIS:

  1. Add a new Visual C# .NET Windows application named Example4_7 to the solution.

  2. Add references to the .NET assembly System.Runtime.Remoting and the project Example4_1.

  3. Add a new application configuration file (App.config) to the project, and add the following code:

     <?xml version="1.0" encoding="utf-8" ?> <configuration>   <system.runtime.remoting>     <application>       <channels>         <channel ref="http" useDefaultCredentials="true"/>       </channels>       <client>           <wellknown             type= "Example4_1.DbConnect, Example4_1"             url="http://localhost/EC70320/C04/Example4_6/DbConnect.rem"           />       </client>     </application>   </system.runtime.remoting> </configuration> 
  4. Add a TextBox control (txtQuery, with its MultiLine property set to true), a Button control (btnExecute), and a DataGrid control (dgResults) on the form.

  5. Add the following using directives:

     using System.Runtime.Remoting; using Example4_1; 
  6. Add the following code in the class definition:

     DbConnect dbc; 
  7. Double-click the form and add the following code in the Load event handler:

     private void Form1_Load(object sender, System.EventArgs e) {     RemotingConfiguration.Configure("Example4_7.exe.config");     dbc = new DbConnect(); } 
  8. Double-click the Button control and add the following code in the Click event handler:

     private void btnExecute_Click(object sender, System.EventArgs e) {     try     {         dgResults.DataSource = dbc.ExecuteQuery(txtQuery.Text);         dgResults.DataMember = "Results";     }     catch(Exception ex)     {         MessageBox.Show(ex.Message, "Query Execution Error");     } } 
  9. Build and run the project. Enter a query in the text box and click the button. The code invokes a method on the remote object hosted by IIS and binds the results to the DataGrid control.


    Team-Fly    
    Top


    MCAD Developing XML Web Services and Server Components with Visual C#. NET and the. NET Framework Exam Cram 2 (Exam Cram 70-320)
    Managing Globally with Information Technology
    ISBN: 789728974
    EAN: 2147483647
    Year: 2002
    Pages: 179

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net