Remote Objects, Clients, and Servers


Before stepping into the details of the .NET Remoting architecture, this section looks briefly at a remote object and a very small, simple client-server application that uses this remote object. After that the required steps and options are discussed in more detail.

Figure 37-3 shows the major .NET Remoting classes in the client and server application. The remote object that will be implemented is called Hello. HelloServer is the main class of the application on the server, and HelloClient is used for the client.

image from book
Figure 37-3

Remote Objects

Remote objects are required for distributed computing. An object that should be called remotely from a different system must be derived from System.MarshalByRefObject. MarshalByRefObject objects are confined to the application domain in which they were created. This means that they are never passed across application domains; instead, a proxy object is used to access the remote object from another application domain. The other application domain can live inside the same process, in another process, or on another system.

A remote object has distributed identity. Because of this, a reference to the object can be passed to other clients, and they will still access the same object. The proxy knows about the identity of the remote object.

The MarshalByRefObject class has, in addition to the inherited methods from the Object class, methods to initialize and to get the lifetime services. The lifetime services define how long the remote object lives. Lifetime services and leasing features are dealt with later in this chapter.

To see .NET Remoting in action, create a Class Library for the remote object. The class Hello derives from System.MarshalByRefObject. In the constructor a message is written to the console that provides information about the object’s lifetime. In addition, add the method Greeting() that will be called from the client.

To distinguish easily between the assembly and the class in the following sections, give them different names in the arguments of the method calls used. The name of the assembly is RemoteHello, and the class is named Hello:

  using System; namespace Wrox.ProCSharp.Remoting {    public class Hello : System.MarshalByRefObject    {       public Hello()       {          Console.WriteLine("Constructor called");       }              public string Greeting(string name)       {          Console.WriteLine("Greeting called");          return "Hello, " + name;       }    } } 

A Simple Server

For the server, create a new C# console application called HelloServer. To use the TcpServerChannel class, you have to reference the System.Runtime.Remoting assembly. It’s also required that you reference the RemoteHello assembly that was created earlier.

In the Main() method, an object of type System.Runtime.Remoting.Channels.Tcp.TcpServerChannel is created with the port number 8086. This channel is registered with the System.Runtime.Remoting .Channels.ChannelServices class to make it available for remote objects. The remote object type is registered by calling the methodRemotingConfiguration.RegisterWellKnownServiceType().

In the example, the type of the remote object class, the URI used by the client, and a mode are specified. The mode WellKnownObject.SingleCall means that a new instance is created for every method call; in the sample application no state is held in the remote object.

Tip 

.NET Remoting allows creating stateless and stateful remote objects. In the first example, well-known single-call objects that don’t hold state are used. The other object type is called client-activated. Client-activated objects hold state. Later in this chapter, when looking at the object activation sequence, you learn more details about these differences and how these object types can be used.

After registration of the remote object, it is necessary to keep the server running until a key is pressed:

  using System; using System.Collections.Generic; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace Wrox.ProCSharp.Remoting {    class Program    {       static void Main()       {          TcpServerChannel channel = new TcpServerChannel(8086);          ChannelServices.RegisterChannel(channel, true);          RemotingConfiguration.RegisterWellKnownServiceType(                typeof(Hello), "Hi", WellKnownObjectMode.SingleCall);          Console.WriteLine("Press return to exit");          Console.ReadLine();       }    } } 

A Simple Client

The client is again a C# console application: HelloClient. With this project, you also have to reference the System.Runtime.Remoting assembly so that the TcpClientChannel class can be used. In addition, you have to reference the RemoteHello assembly. Although the object will be created on the remote server, the assembly is needed on the client for the proxy to read the type information during runtime.

In the client program, create a TcpClientChannel object that’s registered in ChannelServices. For the TcpChannel, you can use the default constructor, so a free port is selected. Next, the Activator class is used to return a proxy to the remote object. The proxy is of type System.Runtime.Remoting.Proxies .__TransparentProxy. This object looks like the real object because it offers the same methods. The transparent proxy uses the real proxy to send messages to the channel:

  using System; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Tcp; namespace Wrox.ProCSharp.Remoting {    class Program    {       static void Main()       {          Console.WriteLine("Press return after the server is started");          Console.ReadLine();          ChannelServices.RegisterChannel(new TcpClientChannel(), true);          Hello obj = (Hello)Activator.GetObject(                                       typeof(Hello), "tcp://localhost:8086/Hi");          if (obj == null)          {             Console.WriteLine("could not locate server");             return;          }          for (int i=0; i< 5; i++)          {             Console.WriteLine(obj.Greeting("Christian"));          }       }    } } 

Tip 

A proxy is an object used by the client application in place of the remote object. Proxies that are used in Chapter 36, “Web Services with ASP.NET,” have a similar functionality to the proxies in this chapter. The implementation of proxies for Web services and proxies for .NET Remoting is very different.

Now you can start the server and then the client program. Within the client console, the text Hello, Christian appears five times. With your server console window you can see the output shown in Figure 37-4: With every method call a new instance gets created because the WellKnownObjectMode.SingleCall activation mode was selected.

image from book
Figure 37-4




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

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