c# 遠端呼叫 / Remoting IpcChannel sample
阿新 • • 發佈:2020-08-27
.
遠端呼叫
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() + "\t" + 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"); /*註冊通道服務端*/ ChannelServices.RegisterChannel(channel, false); /*設定模式為 Singleton */ RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal), "MessageMarshal.TestMessageMarshal", WellKnownObjectMode.SingleCall); txtLog.AppendText("started ..." + "\r\n"); /*接收客戶端事件*/ TestMessageMarshal.SendMessageEvent += new SendMessageHandler(TestMessageMarshal_SendMessageEvent); Console.Read(); } void TestMessageMarshal_SendMessageEvent(string messge) { txtLog.AppendText(messge+"\r\n"); } } }
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(); 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 ,簡單來講,繼承此類的物件可以跨越應用程式域邊界被引用,甚至被遠端引用.