.NET Remoting Basic(2)激活方式

一.服务器激活(Server-Activated Objects / SAO)

1.测试数据


public interface IMyRemoteObject
 {
   void SetValue(int newval);
   int GetValue();
 }
class MyRemoteObject: MarshalByRefObject, IMyRemoteObject
  {
    int myvalue;
 
    public MyRemoteObject() 
    {
      Console.WriteLine("MyRemoteObject.Constructor: New Object created");
    }
 
    public MyRemoteObject(int startvalue) 
    {
      Console.WriteLine("MyRemoteObject.Constructor: .ctor called with {0}",startvalue);
      myvalue = startvalue;
    }
 
    public void SetValue(int newval) 
    {
      Console.WriteLine("MyRemoteObject.setValue(): old {0} new {1}",myvalue,newval);
      myvalue = newval;
    }
    public int GetValue() 
    {
      Console.WriteLine("MyRemoteObject.getValue(): current {0}",myvalue);
      return myvalue;
    }
  }

2.服务器端激活

RemotingConfiguration类的RegisterWellKnownServiceType方法注册,激活方式WellKnownObjectMode

image_2

static void Main(string[] args)
 {
   Console.WriteLine ("ServerStartup.Main(): Server started");
 
   HttpChannel chnl = new HttpChannel(1234);
   ChannelServices.RegisterChannel(chnl);
   RemotingConfiguration.RegisterWellKnownServiceType(
     typeof(MyRemoteObject),
     "MyRemoteObject.soap", 
     WellKnownObjectMode.Singleton);
 
   // the server will keep running until keypress.
   Console.ReadLine();
 }

4.客户端测试代码

static void Main(string[] args)
 {
   HttpChannel channel = new HttpChannel();
   ChannelServices.RegisterChannel(channel);
         
   IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
     typeof(IMyRemoteObject),
     "http://localhost:1234/MyRemoteObject.soap");
   Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
 
   int tmp = obj.GetValue();
 
   Console.WriteLine("Client.Main(): Original server side value: {0}",tmp);
   Console.WriteLine("Client.Main(): Will set value to 42");
   obj.SetValue(42);
   tmp = obj.GetValue();
   Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
 
   Console.ReadLine();
 }

3.Singleton激活方式测试结果

image_4

上面结果说明是同一个实例调用

4.SingleCall激活方式测试结果

WellKnownObjectMode枚举改为WellKnownObjectMode.SingleCall

image_6

上面结果说明即使是同个对象,再次调用方法也是重新实例化的.

二.封送拆收处理 (Unmarshaling)

术语来自MSDN

ObjRef 是对象的可序列化表示,用于跨应用程序域边界传输对象引用。为对象创建 ObjRef 称为封送。可以通过信道将 ObjRef 传输到另一个应用程序域(可能在另一个进程或计算机上)。达到其他应用程序域后,需立即分析 ObjRef,以便为该对象创建一个代理(通常连接到实际的对象)。此操作称为拆收处理 (Unmarshaling)。

1.服务器端

class MyRemoteObject: MarshalByRefObject, IMyRemoteObject
 {
     int myvalue;
 
     public MyRemoteObject() 
     {
         Console.WriteLine("MyRemoteObject.Constructor: New Object created");
     }
 
     public MyRemoteObject(int startvalue) 
     {
         Console.WriteLine("MyRemoteObject.Constructor: .ctor called with {0}",startvalue);
         myvalue = startvalue;
     }
 
     public void SetValue(int newval) 
     {
         Console.WriteLine("MyRemoteObject.setValue(): old {0} new {1}",myvalue,newval);
         myvalue = newval;
     }
     public int GetValue() 
     {
         Console.WriteLine("MyRemoteObject.getValue(): current {0}",myvalue);
         return myvalue;
     }
 }
 
 class ServerStartup
 {
     static void Main(string[] args)
     {
         Console.WriteLine ("ServerStartup.Main(): Server started");
 
         HttpChannel chnl = new HttpChannel(1234);
         ChannelServices.RegisterChannel(chnl);
 
         MyRemoteObject obj = new MyRemoteObject(4711);
         RemotingServices.Marshal(obj,"MyRemoteObject.soap");
 
         // the server will keep running until keypress.
         Console.ReadLine();
     }
 }

2.客户端

class Client
 {
     static void Main(string[] args)
     {
         HttpChannel channel = new HttpChannel();
         ChannelServices.RegisterChannel(channel);
         
         IMyRemoteObject obj = (IMyRemoteObject) Activator.GetObject(
             typeof(IMyRemoteObject),
             "http://localhost:1234/MyRemoteObject.soap");
         Console.WriteLine("Client.Main(): Reference to rem.obj. acquired");
 
         int tmp = obj.GetValue();
 
         Console.WriteLine("Client.Main(): Original server side value: {0}",tmp);
         Console.WriteLine("Client.Main(): Will set value to 42");
         obj.SetValue(42);
         tmp = obj.GetValue();
         Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
 
         Console.ReadLine();
     }    
 }


测试结果

image_8

与服务器端Singleton激活方式结果相同

三.客户端激活(Client-Activated Objects / CAO)

可以在客户端调用 new 或 Activator.CreateInstance 创建对象

1.服务器端

static void Main(string[] args)
 {
     Console.WriteLine ("ServerStartup.Main(): Server started");
 
     HttpChannel chnl = new HttpChannel(1234);
     ChannelServices.RegisterChannel(chnl);
 
     RemotingConfiguration.ApplicationName = "MyServer";
     RemotingConfiguration.RegisterActivatedServiceType(
                              typeof(MyRemoteObject));
 
     // the server will keep running until keypress.
     Console.ReadLine();
 }


2.客户端

static void Main(string[] args)
 {
     HttpChannel channel = new HttpChannel();
     ChannelServices.RegisterChannel(channel);
 
     RemotingConfiguration.RegisterActivatedClientType(
         typeof(Server.MyRemoteObject),
         "http://localhost:1234/MyServer");
     
     Console.WriteLine("Client.Main(): Creating first object");
 
     Server.MyRemoteObject obj1 = new Server.MyRemoteObject();
 
     obj1.setValue(42);
 
     Console.WriteLine("Client.Main(): Creating second object");
     Server.MyRemoteObject obj2 = new Server.MyRemoteObject();
     obj2.setValue(4711);
 
     Console.WriteLine("Obj1.getValue(): {0}",obj1.getValue());
     Console.WriteLine("Obj2.getValue(): {0}",obj2.getValue());
 
     Console.ReadLine();
 }    


3.测试结果

image_10

(2)使用工厂

服务器端

class MyRemoteFactory: MarshalByRefObject,IRemoteFactory 
 {
     public MyRemoteFactory() {
         Console.WriteLine("MyRemoteFactory.ctor() called");
     }
     public IRemoteObject getNewInstance() 
     {
         Console.WriteLine("MyRemoteFactory.getNewInstance() called");
         return new MyRemoteObject();
     }
 
     public IRemoteObject getNewInstance(int initvalue) 
     {
         Console.WriteLine("MyRemoteFactory.getNewInstance(int) called");
         return new MyRemoteObject(initvalue);
     }
 }
static void Main(string[] args)
 {
     Console.WriteLine ("ServerStartup.Main(): Server started");
 
     HttpChannel chnl = new HttpChannel(1234);
     ChannelServices.RegisterChannel(chnl);
 
     RemotingConfiguration.RegisterWellKnownServiceType(
         typeof(MyRemoteFactory),
         "factory.soap",
         WellKnownObjectMode.Singleton);
 
     // the server will keep running until keypress.
     Console.ReadLine();
 }


注意注册的服务必须继承自MarshalByRefObject

客户端

static void Main(string[] args)
 {
     HttpChannel channel = new HttpChannel();
     ChannelServices.RegisterChannel(channel);
 
     Console.WriteLine("Client.Main(): Creating factory");
     IRemoteFactory fact = (IRemoteFactory) Activator.GetObject(
         typeof(IRemoteFactory),
         "http://localhost:1234/factory.soap");
     
     Console.WriteLine("Client.Main(): Acquiring first object from factory");
     IRemoteObject obj1 = fact.getNewInstance();
     obj1.setValue(42);
 
     Console.WriteLine("Client.Main(): Acquiring second object from factory");
     IRemoteObject obj2 = fact.getNewInstance(4711);
 
     Console.WriteLine("Obj1.getValue(): {0}",obj1.getValue());
     Console.WriteLine("Obj2.getValue(): {0}",obj2.getValue());
 
     Console.ReadLine();
 }
原文地址:https://www.cnblogs.com/Clingingboy/p/1809569.html