.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()); }
得到的结论:
- 管是对象的创建,还是对象方法的执行,都在服务端(远程)执行。
- 服务端为每一个客户端(两次RunTest()调用,各创建了一个对象)创建其专属的对象,为这个客户提供服务,并且保存状态(第二次调用ShowCount()的值基于第一次调用ShowCount()之后count的值)。
- 可以从远程获取到方法执行的返回值。(客户端从GetCount()方法获得了返回值)
- 使用客户激活方式时,远程对象在调用new操作时创建
2使用SingleTon模式调用
只需要在客户端将Main函数中ClientActivated();换成 ServerActivatedSingleton()或者ServerActivatedSingleCall();即可,
当使用Singleton模式时,服务端在第一次请求时创建一个对象(构造函数只调用了一次)。对于后继的请求仅使用这个对象进行服务(即使再次调用构造函数也不会创建对象),同时多个客户端共享同一个对象的状态(ShowCount()的值累加)。
对于SingleCall方式来说,对象对每一次方法调用提供服务,换言之,对于每一次方法调用,创建一个全新的对象为其服务,在方法执行完毕后销毁对象