一下内容摘自百度百科和
http://hillstone.blog.hexun.com/45603103_d.html
Remoting的通道有两种Tcp和HTTP,在.net种,
System.Runtion.Remoting.Channels种定义了IChannel接口,IChannel接口包括
了TcpChannel通道类型和Http通道类型。
TcpChannel类型放在名字空间System.Runtime.Remoting.Channels.Tcp种。Tcp
通道提供了基于Socket的传输工具,使用Tcp协议来跨越Remoting边界传输序列
化的小溪流,TcpChannel类型默认使用二进制格式序列化消息对象,因此它具有
更高的传输特性。HttpChannel类型放在
System.Runtime.Remoting.Channels.Http中,它提供了一种使用HTTP协议,使
其能在internet上穿越防火墙传输序列化消息流。默认情况下,HttpChannel类
型使用Soap格式序列化消息对象,因此它具有更好的互操作性,
通常在局域网中,我们更多的使用TcpChannel;如果要穿越防火墙,则使用
HttpChannel.
在访问远程类型的一个对象实例之前,必须通过一个Activation的进行进行初始
化,这种客户端通过通道来创建远程对象,称为对象的激活,在Remoting中,远
程对象的激活分为两类:服务器端激活和客户端激活
服务器端激活又叫做Wellknow方式,因为会在服务器应用程序激活对象实例前会
在一个众所周知的统一资源标识符(URL)上来发布这个类型。
服务器激活又分为SingleTon模式和SingleCall模式
SingleTon模式:为所有客户端创建同一个对象实例,类似asp.net种的
application.
SingleCall模式:为每个客户端创建单独的对象实例,类型asp.net种的session
。
客户端激活:Remoting在激活每个对象实例的时候,会给每个客户端激活的类型
指派一个URL。客户端激活模式一旦获得客户端的请求,将为每一个客户端简历
一个引用实例。
服务器的SingleCall和客户端激活是有区别的。
首先,对象实例创建时间不一样,客户端激活方式是客户端一旦发生调用请求,
就实例化,而SingleCall则要等到调用对象方法的时候创建。其次,SingleCall
模式激活的对是无状态的,对象生命周期由GC管理,而客户端激活的对象是有状
态的,其生命周期可自定义,其三,两种激活模式在服务器端和客户端实现的方
法不一样,尤其是在客户端,SingleCall模式是由GetObject()来激活,它调用
对象默认的构造函数。而客户端激活方式,则通过CreateInstance()来激活,它
可以传递参数,所以可以在调用自定义的构造函数来创建实例。
客户端在获取服务器对象时,并不是获取实际的服务器对象,而是获取它的引用
,因此在所传递的远程对象必须继承MrshalByRefObject类。MSDN中对
MarshalByRefObject的说明是:MarshalByRefObject是那些通过使用代理交换消
息来跨越应用程序来跨越应用程序域边界进行通信的对象的基类。不是从
MarshalByRefObject继承的对象会以隐式方式按值封送。当远程应用程序引用一
个按值封送的对象时,将跨越远程处理边界传递该对象的副本。因为您希望是用
代理方法而不是副本方法进行通信,因此需要继承MarshallByRefObject.
在Remoting种能传递的的远程对象是各种类型,包括复杂的DataSet对象,只要
它能够被序列化,远程对象也可以包括事件。
Remoting的服务端分为三步
1。注册通道
2。注册远程对象
3。注销通道
一个简单的例子
公共类,用于广播出去的类,这样客户端就可以访问这个类了。
//必须继承自MarshalByRefObject 否则传递的是副本而不是引用
public class CommonClass:MarshalByRefObject
{
public static List<string> lstGetValue = new List<string>();
public CommonModel ShowMessage(string message)
{
CommonModel model = new CommonModel();
model.message = "Remoting:" + message;
return model;
}
}
//自定义对象必须可序列化
[Serializable]
public class CommonModel
{
public string message
{
get;
set;
}
}
服务端
private void Resigter()
{
TcpChannel channel = new TcpChannel(1234);
ChannelServices.RegisterChannel(channel, false);
}
private void CreateObject()
{
//这里的typeof 必须是广播的类,而不能是实体,切记切记
RemotingConfiguration.RegisterWellKnownServiceType(typeof(CommLibary.CommonClass), "test123", WellKnownObjectMode.SingleCall);
}
private void StopObject()
{
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
if (channel.ChannelName == "test123")
{
TcpChannel tcpChannel = (TcpChannel)channel;
tcpChannel.StopListening(null);
ChannelServices.UnregisterChannel(tcpChannel);
break;
}
}
}
客户端:
private void RegisterChannel()
{
TcpChannel tcpChannel = new TcpChannel();
ChannelServices.RegisterChannel(tcpChannel, false);
}
private void Execute()
{
CommLibary.CommonClass commClass = (CommLibary.CommonClass)Activator.GetObject(typeof(CommLibary.CommonClass), "tcp://localhost:1234/test123");
CommLibary.CommonModel message = commClass.ShowMessage(textBox1.Text);
//MessageBox.Show(message.message);
MessageBox.Show(message.message);
}