IPC實現同一機器不同進程間通信
我們知道不同進程間的通信方式主要有3種:http、IPC、web service方案。本文主要講IPC通信。
IPC通信可以實現當客戶端和用戶端在不同進程時的數據通信和消息處理工作。通信的核心在於客戶端(Ipc Client)和服務端(Ipc Server)之間的通信通道IpcChannel,進程之間的共享空間:遠程MarshalByRefObject對象。
IPC通信的過程如下:
- 伺服器端註冊通道,初始化MarshalByRefObject對象,並通過Activation類的方法激活對象,為遠程MarshalByRefObject對象生產客戶端訪問對象的uri地址。
- 遠程MarshalByRefObject對象的激活方式:
- 伺服器端激活
A)SingleTon激活方式如下
RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal),"test", WellKnownObjectMode.Singleton)
B)SingleCall模式
RemotingConfiguration.RegisterWellKnownServiceType(typeof(TestMessageMarshal),"test", WellKnownObjectMode.SingleCall);
3.客戶端註冊通道,初始化MarshalByRefObject對象,並uri地址訪問。
遠程對象:
using System;namespace IpcClientTool{ public class IpcRemoteObject : MarshalByRefObject { private const string IPC_PORT_NAME = "hi"; private string name = ""; private int salary = 0; public delegate void MessageHandler(String message); public event MessageHandler MessageEvent; public IpcRemoteObject() { Console.WriteLine("RemoteObject Constructed!"); } public void SendMessage(string message) { //消息處理 if (MessageEvent != null) { MessageEvent(message); } } public void GetResponse(int salary) { Console.WriteLine("Get Response from " + name + "!"); this.salary = salary; } public int GetSalary() { return this.salary; } }}
服務端代碼如下:
using System;using System.Collections.Generic;using System.Runtime.Remoting;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Ipc;using System.Threading;namespace IpcClientTool{ class IpcServer { public string company; private int salary; public Dictionary<string, int> salarys; private IpcRemoteObject remoteObject; static void Main(string[] args) { //start server var ipcServer = new IpcServer(); ipcServer.LoadData(); ipcServer.StartIpcServer(); //使用線程去獲取消息 //Thread t = new Thread(new ThreadStart(ReciveMessage)); Console.ReadLine(); } private static AutoResetEvent e = new AutoResetEvent(false); private void StartIpcServer() { IpcServerChannel chan = new IpcServerChannel("ServerChannel"); ChannelServices.RegisterChannel(chan,false); //register RemoteObject //RemotingConfiguration.RegisterWellKnownServiceType(typeof(IpcRemoteObject),"RemoteObject", WellKnownObjectMode.Singleton); remoteObject = new IpcRemoteObject(); RemotingServices.Marshal(remoteObject, "RemoteObject",typeof(IpcRemoteObject)); Console.WriteLine("Start Server!"); //客戶端事件處理 remoteObject.MessageEvent += ReciveMessage; } private void LoadData() { company = "FujiXerox"; salarys = new Dictionary<string, int>(); salarys.Add("Carter",3); salarys.Add("Peng",4); } public int GetSalary(String name) { return this.salarys[name]; } private void ReciveMessage(string name) { Console.WriteLine(name); //得到消息後返回應答 this.salary = this.salarys[name]; remoteObject.GetResponse(this.salary); } }}
客戶端代碼如下:
using System;using System.Runtime.Remoting.Channels;using System.Runtime.Remoting.Channels.Ipc;namespace IpcClientTool{ class IpcClient { public IpcClient() { IpcClientChannel chan = new IpcClientChannel(); ChannelServices.RegisterChannel(chan, false); } static void Main(string[] args) { var ipcClient = new IpcClient(); var RemoteObject = new IpcRemoteObject(); RemoteObject = (IpcRemoteObject)Activator.GetObject(typeof(IpcRemoteObject), "ipc://ServerChannel/RemoteObject"); if (RemoteObject == null) { Console.WriteLine("cannot locate server!"); } else { //客戶端消息發送 RemoteObject.SendMessage("Carter"); for (int i = 1; i < 5; i++) { //服務端取得薪水 Console.WriteLine("request success!"); Console.WriteLine("Carters salary is about " + RemoteObject.GetSalary()); } } Console.ReadLine(); } }}
程序運行結果如下:
伺服器端:
客戶端:
推薦閱讀: