REMOTING是.NET自带的一种RPC调用方式。主要解决多个进程间互相的调用。
举例1:如现某一台电脑存在2个进程,进程1上存在一个按钮,点击按钮时会使进程2触发某个方法进行逻辑运算,那么我们存在的问题点在于如何让进程1联通进程2,同时让进程2自己去触发自己的某个方法。
举例2:如某一台电脑存在2个进程,2个进程现在都有可能修改某一个LIST,可以同时向这一个LIST中添加值或者修改值,那么问题在于如何使2个进程操作的对象是同一个对象。
以上两个例子如出现类似场景,那么REMOTING就是你的一个好的选择。
当然,如果多个进程在不同电脑上,只要这几台电脑在同一网络中,REMOTING仍能帮你完成进程间调用,但是这时就不推荐使用REMOTING了,效率和准确度上会比写webserver服务要差。
原理
建立一个公用的对象,该对象在服务端声明并共享出去,各个进程可以取到这个公共的对象,并修改该对象。如希望实现一个进程调用另一个进程,那么使用代理来实现该目的。TCP连接效率较快,但是基本只能用于本机。HTTP效率较慢,但是可以用于局域网。注意,服务端和客户端必须使用相同的协议。
实际使用
建立一个TCP通道
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel, false);
建立一个HTTP通道
HttpChannel channel = new HttpChannel(8226);
ChannelServices.RegisterChannel(channel, false);
在建立的通道上共享一个对象,并且服务名为test
RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal), "test", WellKnownObjectMode.Singleton);
共享对象的另一种方式
MessageMarshal.TestMessageMarshal obj = new MessageMarshal.TestMessageMarshal();
ObjRef objrefWellKnown = RemotingServices.Marshal(obj, "ServiceMessage");
建立一个拥有共享调用的方法的类
/*创建发送消息委托*/
public delegate void SendMessageHandler(string messge);
[Serializable]
public class TestMessageMarshal : MarshalByRefObject
{
private Guid ID { get; set; }
/*新建对象实例时重新创建标识编号*/
public TestMessageMarshal()
{
ID = Guid.NewGuid();
}
/*创建发送消息事件*/
public static event SendMessageHandler SendMessageEvent;
/*发送消息*/
[SoapMethod(XmlNamespace = "MessageMarshal", SoapAction = "MessageMarshal#SendMessage")]
public void SendMessage(string messge)
{
if (SendMessageEvent != null)
SendMessageEvent(ID.ToString() + "\t" + messge);
}
}
}
直接获取共享的类方式(HTTP协议一样)
IPerson obj = (IPerson)Activator.GetObject(typeof(RemotingObjects.IPerson), "tcp://localhost:8080/RemotingPersonService"
通过建立客户端方式获取共享的类
RemotingConfiguration.RegisterWellKnownClientType(typeof(MessageMarshal.TestMessageMarshal), "http://localhost:8226/test");
/*创建消息实体*/
MessageMarshal.TestMessageMarshal TestMessage = new MessageMarshal.TestMessageMarshal();
关闭并取消注册的通道
if (channel != null)
{
channel.StopListening(null);
ChannelServices.UnregisterChannel(channel);
}
注销对象的另一种方式
RemotingServices.Disconnect(obj);