.
远程调用
1. 创建一个远程的可序列化的类,这个类可以在远程调用中用于传输来去,似乎是个公共的类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.Remoting.Metadata; namespace MessageMarshal { /*创建发送消息委托*/ 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() + " " + messge); } } }
2. 创建服务器的类:
using MessageMarshal; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime.Remoting.Channels.Ipc; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ServerApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { TestStartServer(); } void TestStartServer() { /*创建HTTP通道*/ IpcChannel channel = new IpcChannel("test");//或者 IpcServerChannel serverChannel = new IpcServerChannel("test"); /*注册通道服务端*/ ChannelServices.RegisterChannel(channel, false); /*设置模式为 Singleton */ RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal), "MessageMarshal.TestMessageMarshal", WellKnownObjectMode.SingleCall); txtLog.AppendText("started ..." + " "); /*接收客户端事件*/ TestMessageMarshal.SendMessageEvent += new SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read(); } void TestMessageMarshal_SendMessageEvent(string messge) { txtLog.AppendText(messge+" "); } } }
3. 创建客户端类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using MessageMarshal; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Threading; using System.Runtime.Remoting.Channels.Ipc; namespace GPRemoteClient { class Program { static void Main(string[] args) { IpcChannel channel = new IpcChannel();//或者IpcClientChannel channel = new IpcClientChannel("channel2", new BinaryClientFormatterSinkProvider());
ChannelServices.RegisterChannel(channel, false); var testMessageMarshal = (TestMessageMarshal)Activator.GetObject(typeof(MessageMarshal.TestMessageMarshal), "ipc://test/MessageMarshal.TestMessageMarshal"); while (true) { testMessageMarshal.SendMessage("DateTime.Now:" + System.DateTime.Now.ToString()); Console.WriteLine("send message..."); Thread.Sleep(2000); } /*或者下面的代码也可实现这个远程调用效果 IpcChannel channel = new IpcChannel(); ChannelServices.RegisterChannel(channel, false); //注册通道 的 远程处理类型 RemotingConfiguration.RegisterWellKnownClientType(typeof(MessageMarshal.TestMessageMarshal), "ipc://test/MessageMarshal.TestMessageMarshal"); //创建消息实体 MessageMarshal.TestMessageMarshal TestMessage = new MessageMarshal.TestMessageMarshal(); while (true) { TestMessage.SendMessage("DateTime.Now:" + System.DateTime.Now.ToString()); Console.WriteLine("send message..."); Thread.Sleep(2000); } */ } } }
原理的 这个 类TestMessageMarshal : MarshalByRefObject 是继承了MarshalByRefObject ,简单来讲,继承此类的对象可以跨越应用程序域边界被引用,甚至被远程引用.
如果在同一个项目进程里测试 创建服务端和客户端Channel或报 已经注册了某个Channel的错误。因为channel默认名字的原因。
这个时候可以用形如下的方式创建服务端和客户端Channel:
IpcServerChannel serverChannel = new IpcServerChannel("test");
IpcClientChannel channel = new IpcClientChannel("channel2", new BinaryClientFormatterSinkProvider());
还加不同的参数来创建可以如:
Hashtable ht = new Hashtable();
ht["portName"] = "TestChannel";
ht["name"] = "ipc";
ht["authorizedGroup"] = "Everyone";//可设置权限。
IpcChannel channel = new IpcChannel(ht,null,null);