图1:.NET Remoting构架图
通常用到的Remoting的概念有:
Remoting Channel:这是指客户端和服务器端的通信协议,如我们可以使用TCP, HTTP协议。
Serializer:这是指在传输时采用何种格式来传输数据,如我们可以采用Binary,也可以采用SOAP来传输XML格式的数据.
.NET力图简化这些概念的编程,所以上面所述的协议和格式都可以通过更改配置文件切换。这也是编程人员不用担心的问题。如一段典型的客户端配置文件的内容是:
<CONFIGURATION> <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <CHANNELS> <CHANNEL ref="http" clientConnectionLimit="200"> <CLIENTPROVIDERS> <FORMATTER ref="binary"> </CLIENTPROVIDERS> </CHANNEL> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
服务器端代码
Server.cs using System; using System.Runtime.Remoting; public class Server{ public static void Main(string[] Args){ // Load the configuration file RemotingConfiguration.Configure("server.exe.config"); Console.WriteLine("The server is listening. Press Enter to exit...."); Console.ReadLine(); Console.WriteLine("GC'ing."); GC.Collect(); GC.WaitForPendingFinalizers(); } } |
表1:Server.cs源代码
Server.exe.config <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <SERVICE> <ACTIVATED type="ClientActivatedType, RemoteType"> </SERVICE> <CHANNELS> <CHANNEL ref="http" port="8088"> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
表2:Server.exe.config源代码
RemoteType.cs using System; using System.Runtime.Remoting.Lifetime; using System.Security.Principal; public class ClientActivatedType : MarshalByRefObject{ private int i; // override the lease settings for this object public override Object InitializeLifetimeService(){ return null; } public string RemoteMethod(){ // announce to the server that we've been called. Console.WriteLine("ClientActivatedType.RemoteMethod called."); // report our client identity name i=this.GetHashCode(); return "RemoteMethod called. " + i; } public string RemoteMethod1(){ return "RemoteMethod1 called. " + i; } } |
表3:RemoteType.cs源代码
客户端代码
CAOClient.cs using System; using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; public class Client{ public static void Main(string[] Args){ // Load the configuration file RemotingConfiguration.Configure("CAOclient.exe.config"); ClientActivatedType CAObject = new ClientActivatedType(); Console.WriteLine("Client-activated object: " + CAObject.RemoteMethod()); Console.WriteLine("Client-activated object: " + CAObject.RemoteMethod1()); Console.WriteLine("Press Enter to end the client application domain."); Console.ReadLine(); } } |
CAOClient.exe.config <CONFIGURATION> <SYSTEM.RUNTIME.REMOTING> <APPLICATION> <CLIENT url="http://localhost:8088"> <ACTIVATED type="ClientActivatedType, RemoteType"> </CLIENT> <CHANNELS> <CHANNEL ref="http" port="0"> </CHANNELS> </APPLICATION> </SYSTEM.RUNTIME.REMOTING> </CONFIGURATION> |
csc /target:library RemoteType.cs csc Server.cs csc –reference:RemoteType.dll CAOClient.cs 您会看到三个输出文件:RemoteType.dll, Server.exe 和 CAOClient.exe。 运行Remoting程序 在命令行方式下启动:Server.exe 在命令行方式下启动:CAOClient.exe |
<SERVICE> <ACTIVATED type="ClientActivatedType, RemoteType"> </SERVICE> |
Client-activated object: RemoteMethod Called, 162. Client-activated object: RemoteMethod1 Called, 162. |
public override Object InitializeLifetimeService(){ return null; } |
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconlifetimeleases.asp Single Call 对象 |
<SERVICE> <WELLKNOWN mode="SingleCall" type="ClientActivatedType, RemoteType" objectUri="RemoteType.rem"> </SERVICE> |
<CLIENT url="http://localhost:8088"> <WELLKNOWN type="ClientActivatedType, RemoteType" url="HTTP://localhost:8088/RemoteType.rem"> </CLIENT> |
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 0. |
<SERVICE> <WELLKNOWN mode="Singleton" type="ClientActivatedType, RemoteType" objectUri="RemoteType.rem"> </SERVICE> |
<CLIENT url="http://localhost:8088"> <WELLKNOWN type="ClientActivatedType, RemoteType" url="HTTP://localhost:8088/RemoteType.rem"> </CLIENT> |
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 78. |
Client-activated object: RemoteMethod Called, 78. Client-activated object: RemoteMethod1 Called, 78. |
三种对象的简单比较
从上面的比较中我们可以看出,在三种Server端对象中,Singleton的效率最高,但是所有客户端的调用都只能维持一个Server对象;Client Activated的效率最低,但是它对Remoting的屏蔽最好,就像本地调用对象一样。您可以根据不同的使用场景选择不同的Remoting对象。
Remoting和Web Service区别
Remoting和Web Servcie到底有什么样的差别呢?下表是一个简单的比较:
由于Web Service是一个简单的松耦合结构,所以对于对象的状态不予保存。这一点有点像Remoting中的Single Call对象。同样,Web Service目前还不支持Event和回调函数。相比较来说,Remoting还支持效率较高的Binary编码方式。
但是,Remoting只能够运行在.NET Framework之上,而Web Service相应就享有更多、更灵活的选择。