星星之火

燎原之势不可挡
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Remoting

Posted on 2012-09-27 14:28  星星之火116  阅读(385)  评论(0编辑  收藏  举报

.Net Remoting 技术是.NET平台上实现分布式对象系统的框架,它可以用于访问另一个应用程序域(也可以是另一个服务器)中的对象,可以是进程间的,也可以是不同系统的进程间,这种CS式的通讯机制更为快速方便。

其实质就是:客户端创建服务端对象的代理并调用其方法,通过信道网络传输到服务端,在服务端上处理客户端传递过来的参数数据并返回处理结果(如果有的话)给客户端的接收变量。这种方式与传统上的方法调用明显不同,它轻松实现了数据的分布式处理

Remoting的应用一般由三部分构成,远程类,服务端、客户端。其中服务端和客户端都要引入远程类,在整个应用中远程类相当于一个传输数据的载体,并且所有的远程类必须继承自System.MarshalByRefObject,客户端相当于调用方,服务端相当于执行方。

基本的操作流程如下:

1、创建服务程序集(ServerAssembly)

 
2、创建宿主应用程序(服务器端ServerConsole)  

2、1、注册通道

IChannelReceiver tcpChnl = newTcpChannel(8501);

ChannelServices.RegisterChannel(tcpChnl, false);

 
2、2、注册实例RemotingConfiguration.RegisterActivatedServiceType(t);  
3、客户端应用程序(ClientControl)  

3、1、册客户激活对象

string url = "tcp://127.0.0.1:8501"; RemotingConfiguration.RegisterActivatedClientType(t, url);

 
4.程序运行测试  

4、1、服务端   

RegisterChannel(); // 注册通道 ClientActivated(); // 客户激活方式

 

4、2、客户端

ClientActivated(); // 客户激活方式 RunTest("Olive", "My"); RunTest("Only", "Love");

 
 

具体的Demo如下(参考自博客园Jimmy Zhang)

1、创建服务程序集(ServerAssembly)

{

publicclassDemoClass:MarshalByRefObject { privateint count = 0; public DemoClass() { Console.WriteLine(" ======= DomoClass Constructor ======="); } publicvoid ShowCount(string name) { count++; Console.WriteLine("{0},the count is {1}.", name, count); } // 打印对象所在的应用程序域 publicvoid ShowAppDomain() { AppDomain currentDomain = AppDomain.CurrentDomain; Console.WriteLine(currentDomain.FriendlyName); } publicint GetCount() { return count;}}

}

2、创建宿主应用程序(服务器端ServerConsole)

{

      1、注册通道

privatestaticvoid RegisterChannel() { // 创建通道实例 // IChannel tcpChnl = newTcpChannel(8501); IChannelReceiver tcpChnl = newTcpChannel(8501);
// 注册tcp通道 ChannelServices.RegisterChannel(tcpChnl, false);
// 注册http通道 IChannel httpChnl = newHttpChannel(8502); ChannelServices.RegisterChannel(httpChnl, false); }

      2、注册实例

客户激活对象的注册方式需要使用RemotingConfiguration类型的RegisterActivatedServiceType()静态方法:

// 注册 客户激活对象 Client Activated Object privatestaticvoid ClientActivated() { Console.WriteLine("方式: Client Activated Object"); Type t = typeof(DemoClass); RemotingConfiguration.RegisterActivatedServiceType(t); }

服务激活对象 可以使用RemotingConfiguration类型的 RegisterWellKnownServiceType()静态方法:

// 注册 服务激活对象 SingleCall privatestaticvoid ServerActivatedSingleCall() { Console.WriteLine("方式: Server Activated SingleCall"); Type t = typeof(DemoClass); RemotingConfiguration.RegisterWellKnownServiceType( t, "ServerActivated", WellKnownObjectMode.SingleCall); }
// 注册 服务端激活对象 Singleton privatestaticvoid ServerActivatedSingleton() { Console.WriteLine("方式: Server Activated Singleton"); Type t = typeof(DemoClass); RemotingConfiguration.RegisterWellKnownServiceType( t, "ServerActivated", WellKnownObjectMode.Singleton); }

}

 

3、客户端应用程序(ClientControl)

 

// 注册客户激活对象 privatestaticvoid ClientActivated() { Type t = typeof(DemoClass);
// 下面两个 url 任选一个 string url = "tcp://127.0.0.1:8501"; //string url = "tcp://127.0.0.1:8501/SimpleRemote"; RemotingConfiguration.RegisterActivatedClientType(t, url); }
// 注册服务激活对象 privatestaticvoid ServerActivated() { Type t = typeof(DemoClass); string url = "tcp://127.0.0.1:8501/SimpleRemote/ServerActivated"; RemotingConfiguration.RegisterWellKnownClientType(t, url); }

 

4、运行测试

客户端激活模式

客户激活方式

服务端的Main()代码如下:

staticvoid(string[] args) { RegisterChannel(); // 注册通道 ClientActivated(); // 客户激活方式 Console.WriteLine("服务开启,可按任意键退出... "); Console.ReadKey(); }

客户端的Main()代码如下:

static void (string[] args) { // 注册远程对象 ClientActivated(); // 客户激活方式
RunTest("Jimmy", "Zhang"); RunTest("Bruce", "Wang");
Console.WriteLine("客户端运行结束,按任意键退出..."); Console.ReadKey(); }
private static void RunTest(string firstName, string familyName) { DemoClass obj = newDemoClass(); obj.ShowAppDomain(); obj.ShowCount(firstName); Console.WriteLine("{0}, the count is {1}. ",firstName, obj.GetCount());
obj.ShowCount(familyName); Console.WriteLine("{0}, the count is {1}.",familyName, obj.GetCount()); }

得到的结论:

  1. 管是对象的创建,还是对象方法的执行,都在服务端(远程)执行。
  2. 服务端为每一个客户端(两次RunTest()调用,各创建了一个对象)创建其专属的对象,为这个客户提供服务,并且保存状态(第二次调用ShowCount()的值基于第一次调用ShowCount()之后count的值)。
  3. 可以从远程获取到方法执行的返回值。(客户端从GetCount()方法获得了返回值)
  4. 使用客户激活方式时,远程对象在调用new操作时创建

2使用SingleTon模式调用

只需要在客户端将Main函数中ClientActivated();换成 ServerActivatedSingleton()或者ServerActivatedSingleCall();即可,

当使用Singleton模式时,服务端在第一次请求时创建一个对象(构造函数只调用了一次)。对于后继的请求仅使用这个对象进行服务(即使再次调用构造函数也不会创建对象),同时多个客户端共享同一个对象的状态(ShowCount()的值累加)。

对于SingleCall方式来说,对象对每一次方法调用提供服务,换言之,对于每一次方法调用,创建一个全新的对象为其服务,在方法执行完毕后销毁对象