.
遠程調用
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");//或者 IpcServerChannel serverChannel = new IpcServerChannel("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();//或者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);
