Remoting基础
基本原理
当客户端创建远程RemotableClass的一个实例,.NET框架在客户端应用程序域中产生一个代理。该代理看起来就像实际对象。代理收到调用后,通过通道连接到远程的对象。
一、编写步骤
第一步
编写一个DLL,其中包含所要Remottable的类
public class RemotableClass:MarshalByRefObject
{
….
}
第二步
服务器进程注册该remotable 类以便其他应用程序可以激活。根据该对象是如何激活,服务器通过两种静态方法来注册:RegisterActivatedServiceType或者RegisterWellKnownServiceType。下面的语句使用RegisterWellKnownServiceType来注册RemotableClass,以便远程激活。
RemotingConfiguration.RegisterWellKnownServiceType(
Typeof(RemotableClass), //Remotable类
“RemoteObject”, // Remotable类的URI
WellKnownObjectMode.SingleCall); //激活模式
第一个参数是指能远程化的类。
第二个是指客户端使用来激活对象的URI----也就是客户端告诉服务器来激活
RemotableClass实例的URI。
第三个参数指定激活模式。有两种选择。WellKnownObjectMode.SingleCall是指为客户端的每一次调用创建一个新的实例。WellKnownObjectMode.Singleton是指创建一个RemotableClass实例来处理所有客户端的调用。
第三步
为了使客户端可以使用RemotableClass,服务器进程必须创建,注册一个通道。该通道提供对象和远程客户端交流的一个渠道。在服务器端,.NET框架提供了两种通道:
System.Runtime.Remoting.Channels.Tcp.TcpServerChannel:可以接受远程客户端的TCP连接。
System.Runtime.Remoting.Channels.Http.HttpServerChannel:接受HTTP连接。
下面的语句创建一个在1234端口监听的TcpServerChannel通道,并用.NET框架注册:
TcpServerChannel channel = new TcpServerChannel(1234);
ChannelServices.RegisterChannel(channel);
下面的语句注册了一个在1234端口监听的HTTP通道:
HttpServiceChannel channel = new HttpServerChannel(1234);
ChannelServices.RegisterChannel(channel);
TcpServerChannel更有效率一点。HttpServerChannel是使用IIS作为远程激活代理时使用的选择。
第四步
在客户端要想创建远程类的一个实例,也必须做一些注册。
第一必须注册一个客户端通道。.NET框架提供了两种类型的客户端通道:TcpClientChannel和HttpClientChannel,分别和服务器端通道相对应。
第二,如果客户端想使用new操作符来生产远程对象,必须将远程对象注册到本地应用程序域。
RemotingConfiguration.RegisterWellKnownClientType是在客户端注册一个类。
RemotingConfiguration.RegisterWellKnownServiceType是在服务器上注册一个类。
下面的代码在客户端注册了一个TCP通道,而且也将RemotableClass注册到本地应用程序域中:
TcpClientChannel channel = new TcpClientChannel();
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownClientType(
Typeof(RemotableClass),
“tcp://localhost:1234/RemoteObject”);
第二个参数是指远程对象的URL。
协议必须匹配应用程序注册的通道协议。
可以使用机器名或者IP地址来替换localhost。
端口数必须好服务器端监听的端口数一样。
对象URI,必须和服务器用RegisterWellKnownServiceType注册的匹配。
第五步
在客户端使用new来产生代理:
RemotableClass rc = new RemotableClass();
这个操作在客户端应用程序域中产生一个代理,返回RemotableClass的一个引用。
二、实际范例
ClockServer.cs
using System;
public class Clock : MarshalByRefObject
{
public string GetCurrentTime ()
{
return DateTime.Now.ToLongTimeString ();
}
}
TimeServer.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
class MyApp
{
static void Main ()
{
TcpServerChannel channel = new TcpServerChannel (1234);
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownServiceType
(typeof (Clock), "Clock", WellKnownObjectMode.SingleCall);
Console.WriteLine ("Press Enter to terminate...");
Console.ReadLine ();
}
}
TimeClient.cs
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
class MyApp
{
static void Main ()
{
TcpClientChannel channel = new TcpClientChannel ();
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownClientType
(ty