代码改变世界

.NET Remoting Basic(5)-多服务器访问和程序集共享

2010-08-26 22:50  Clingingboy  阅读(497)  评论(0编辑  收藏  举报

一.访问多服务器


多服务器访问即多个服务器端,一个客户端进行访问,可以减缓服务器端的压力,此也是分布式应用的目的所在

1.Server1

开启1234端口,访问MyRemoteObject 对象

class MyRemoteObject: MarshalByRefObject, IRemoteObject
 {
     int myvalue;
 
     public MyRemoteObject() 
     {
         Console.WriteLine("MyRemoteObject.Constructor: New Object created");
     }
 
     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 [1] 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();
     }
 }


2.Server2

开启1235端口,访问MyWorkerObject对象

class MyWorkerObject: MarshalByRefObject, IWorkerObject
     {
 
         public MyWorkerObject() 
         {
             Console.WriteLine("MyWorkerObject.Constructor: New Object created");
         }
 
         public void DoSomething(IRemoteObject usethis) 
         {
             Console.WriteLine("MyWorkerObject.doSomething(): called");
             Console.WriteLine("MyWorkerObject.doSomething(): Will now call " +
                               "getValue() on the remote obj.");
 
             int tmp = usethis.GetValue();
             Console.WriteLine("MyWorkerObject.doSomething(): current value of " + 
                                 "the remote obj.; {0}", tmp);
 
             Console.WriteLine("MyWorkerObject.doSomething(): changing value to 70");
             usethis.SetValue(70);
         }
     }
 
     class ServerStartup
     {
         static void Main(string[] args)
         {
             Console.WriteLine ("ServerStartup.Main(): Server [2] started");
             SoapServerFormatterSinkProvider prov = new SoapServerFormatterSinkProvider();
             prov.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
 
             IDictionary props = new Hashtable();
             props["port"] = 1235;
 
             HttpChannel chan = new HttpChannel(props, null, prov);        
             ChannelServices.RegisterChannel(chan);
             
             RemotingConfiguration.RegisterWellKnownServiceType(
                     typeof(MyWorkerObject),
                     "MyWorkerObject.soap", 
                     WellKnownObjectMode.SingleCall);
 
             // the server will keep running until keypress.
             Console.ReadLine();
         }
     }


3.客户端调用

同时打开1234和1235两个端口获取对象

class Client
 {
     static void Main(string[] args)
     {
 
         HttpChannel channel = new HttpChannel();
         ChannelServices.RegisterChannel(channel);
         
         IRemoteObject obj = (IRemoteObject) Activator.GetObject(
             typeof(IRemoteObject),
             "http://localhost:1234/MyRemoteObject.soap");
         Console.WriteLine("Client.Main(): Reference to rem.obj. on " + 
                           "Server [1] acquired");
 
         Console.WriteLine("Client.Main(): Will set value to 42");
         obj.SetValue(42);
         int tmp = obj.GetValue();
         Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
 
         IWorkerObject workerobj = (IWorkerObject) Activator.GetObject(
             typeof(IWorkerObject),
             "http://localhost:1235/MyWorkerObject.soap");
         Console.WriteLine("Client.Main(): Reference to rem. workerobj. on " +
                           "Server [2] acquired");
 
 
         Console.WriteLine("Client.Main(): Will now call method on Srv [2]");
         workerobj.DoSomething(obj);
 
         tmp = obj.GetValue();
         Console.WriteLine("Client.Main(): New server side value {0}", tmp);
 
         Console.ReadLine();
     }    
 }

二.生成服务器端对象程序集

当以接口的形式获取对象时,服务器端和客户端必须以接口作为中间件的形式存在,就存在着耦合性

可以以代理的形式通过服务器端对象,生成一个代理的dll程序集.这样两者就不存在依赖关系

以soapsuds命令行来生成

image_2

如上图,根据访问地址生成一个meta.dll,然后客户端就可以使用这个程序集了

class Client
 {
     static void Main(string[] args)
     {
         HttpChannel chnl = new HttpChannel();
         ChannelServices.RegisterChannel(chnl);
 
         Console.WriteLine("Client.Main(): creating rem. reference");
         SomeRemoteObject obj = (SomeRemoteObject) Activator.GetObject (
             typeof(SomeRemoteObject),
             "http://localhost:1234/SomeRemoteObject.soap");
 
         Console.WriteLine("Client.Main(): calling doSomething()");
         obj.doSomething();
 
         Console.WriteLine("Client.Main(): done ");
         Console.ReadLine();
     }    
 }