1. 程式人生 > 實用技巧 >c# 遠端呼叫 / Remoting IpcChannel sample

c# 遠端呼叫 / Remoting IpcChannel sample

.

遠端呼叫

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 ,簡單來講,繼承此類的物件可以跨越應用程式域邊界被引用,甚至被遠端引用.