Remoting可建立的Channel有(1)TCP Channel. (2)Http Channel. (3)IPC Channel
.Net 1.1 : TCP Channel、Http Channel.
.Net 2.0 : 之後多了IPC Channel 使用Windows程式間通信系統(IPC:Inter process Communication)
Remoting 的使用流程
1.建立Remoting 物件
2.在Server建立使用Remoting物件的Channel
3.在Client使用Remoting
//------------------ Example --------------------//
1.建立Remoting物件
1.1 建立Interface 1.2.實作Remoting物件 using System;
using System.Collections;
namespace G5.RemotingEvent.ICommon
{
public delegate void PAEventHandler(Hashtable fax);
public interface IG5Business
{
void SendPA(Hashtable fax);
}
}using System;
using System.Collections;
using G5.RemotingEvent.ICommon;namespace G5.RemotingEvent.RemoteObj
{
public class G5Business:MarshalByRefObject,IG5Business
{
// 建立Event
public static event PAEventHandler PASendedEvent;
#region
public void SendPA(Hashtable fax)
{
if (PASendedEvent != null)
{
PASendedEvent(fax);
}
}
#endregion
public override object InitializeLifetimeService()
{
return null;
}
}
}2.在Server建立使用Remoting物件的Channel
2.1 using
//using System.Runtime.Remoting.Channels.Http;
//using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Ipc;
2.2 建立Channel
// IPC Channel
IpcChannel channel = new IpcChannel("G5Channel");
ChannelServices.RegisterChannel(channel);
RemotingConfiguration.RegisterWellKnownServiceType(typeof (G5Business), "G5Loader", WellKnownObjectMode.Singleton);
//TCP Channel
//TcpServerChannel channel = new TcpServerChannel(3210);
//ChannelServices.RegisterChannel(channel, false);
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(G5Business), "G5Loader", WellKnownObjectMode.Singleton);
// Http Channel
// HttpChannel channel = new HttpChannel(8080);
// ChannelServices.RegisterChannel(channel);
// RemotingConfiguration.RegisterWellKnownServiceType(typeof(G5Business),"G5Business.soap",WellKnownObjectMode.Singleton);
G5Business.PASendedEvent += new PAEventHandler(OnPASended);
3.在Client使用Remoting
1.using //using System.Runtime.Remoting.Channels.Http;
//using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels.Ipc;
2.使用Channel
private IG5Business faxBus = null;
// IPC Channel
string stringIpc = "ipc://G5Channel/G5Loader";
faxBus = (IG5Business)Activator.GetObject(typeof(IG5Business), stringIpc);//TCP Channel
//string stringTcp = "tcp://localhost:3210/TestLoader";
//faxBus = (IG5Business)Activator.GetObject(typeof(IG5Business), stringTcp);
//Http Channel
//HttpChannel channel = new HttpChannel(0);
//ChannelServices.RegisterChannel(channel);
//faxBus = (IG5Business)Activator.GetObject(typeof(IG5Business),
// http://localhost:8080/G5Business.soap);參考資料:
http://www.cnblogs.com/idior/archive/2007/01/04/611265.html (原理)
http://www.codeguru.com/csharp/csharp/cs_syntax/remoting/article.php/c9251
2009年2月18日 星期三
C# Remoting
2009年2月16日 星期一
C# 設定和取得機碼(Registry Key)的值
設定機碼(Registry Key)
string keyPathString = "SOFTWARE\\AB Tool";------------------------------------------------------------------------------------------------------------------------------------
Microsoft.Win32.RegistryKey start = Microsoft.Win32.Registry.LocalMachine;
Microsoft.Win32.RegistryKey programName = start.CreateSubKey(keyPathString);
programName.SetValue("Application Path", System.Windows.Forms.Application.StartupPath);
programName.Close();
------------------------------------------------------------------------------------------------------------------------------------取得機碼(Registry Key) 的值
string pathString = null;
string keyPathString = "SOFTWARE\\AB Tool";
Microsoft.Win32.RegistryKey start = Microsoft.Win32.Registry.LocalMachine;
Microsoft.Win32.RegistryKey programName = start.OpenSubKey(keyPathString);
if (programName != null)
{
pathString = (string)programName.GetValue("Application Path");
}
MSMQ
MSMQ
::Microsoft Message Queue(訊息駐列)啟動MSMQ
::C#使用方式
傳訊
1.建立要傳送資料
System.Messaging.Message hashtable_Msg = new System.Messaging.Message(strHashtable, new System.Messaging.BinaryMessageFormatter());
2.指定MSMQ Channel 或建立MSMQ Channel
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
3.傳送到Message Queue
msgQ.Send(hashtable_Msg);
收訊
1.指定MSMQ Channel 或建立MSMQ Channel
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
2.設定這個Message Queue資訊格式
msgQ.Formatter = new System.Messaging.BinaryMessageFormatter();
3.接收Message
strHashtable = ((System.Collections.Hashtable)msgQ.Receive().Body);
//-------------- 範例 ---------------//
傳訊
Hashtable strHashtable = new Hashtable();
double key = 0;
string valueString = "Dispose";
strHashtable.Add(key, valueString);
// 傳送Hashtable 格式資料時,需要使用BinaryMessageFormatter方式傳送
System.Messaging.Message hashtable_Msg = new System.Messaging.Message
(strHashtable, new System.Messaging.BinaryMessageFormatter());System.Messaging.MessageQueue msgQ;
收訊
// 確認是否有用來傳送的Channel存在,在這 Channel 名稱由使用者定為MDSQueue
if (System.Messaging.MessageQueue.Exists(@".\Private$\MDSQueue"))
{
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
}
else
{
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
}
// 使用Message Queue 的 Object 來傳送訊息
try
{
msgQ.Send(hashtable_Msg);
// 中斷在接收訊息的Message Queue Thread
ThreadAll[0].Interrupt();
}
catch
{
}
public void ListenMDSQueue()
{
// Create MessageQueue Object。
System.Messaging.MessageQueue msgQ;
// 確認是否有用來傳送的Channel存在,在這 Channel 名稱由使用者定為MDSQueue
if (System.Messaging.MessageQueue.Exists(@".\Private$\MDSQueue"))
{
msgQ = new System.Messaging.MessageQueue(@".\Private$\MDSQueue");
}
else
{
msgQ = System.Messaging.MessageQueue.Create(@".\Private$\MDSQueue");
}// Always listen MDS Queue until interrupt。
while (true)
{
try
{
// 使用Thread時interrup機制在MessageQueue Receive時無法中斷
// 需要MessageQueue收到訊息釋放Thread的控制,interrup才能有作用
// 可以使用 Sleep機制在進入Receive時,先確定是否有Interrup發生.
System.Threading.Thread.Sleep(80);System.String ContextString = "";
System.Collections.Hashtable strHashtable = new System.Collections.Hashtable();
System.Object o = new System.Object();
System.Type[] arrTypes = new System.Type[2];
arrTypes[0] = strHashtable.GetType();
arrTypes[1] = o.GetType();
// Message 如果沒有定義格式.預設是使用XmlMessageFormatter
// 這個格式無法存放Hashtable型態的訊息,所以改用BinaryMessageFormatter
// msgQ.Formatter = new System.Messaging.XmlMessageFormatter(arrTypes);
msgQ.Formatter = new System.Messaging.BinaryMessageFormatter();
// 收到的訊息轉為Hashtable格式
strHashtable = ((System.Collections.Hashtable)msgQ.Receive().Body);
// Get Type
ContextString = (string)strHashtable[(double)0];
// 如果收到的訊息為"Dispose” 代表傳訊的人要結束接收訊息的動作.那在下一次迴圈Sleep時
// 會執行傳訊的人所下的ThreadAll[0].Interrupt() 指令
if (ContextString == null || !ContextString.Equals("Dispose"))
{
this.setValueTable(strHashtable);
}
}
catch (System.Threading.ThreadInterruptedException e)
{
System.Console.WriteLine("Exception e:"+e.Message);
msgQ.Dispose();
break;
}
}
}private System.Threading.Thread[] ThreadAll = new System.Threading.Thread[2];
private void StartListenMQThreads()
{
ThreadAll[0] = new System.Threading.Thread(new System.Threading.ThreadStart(ListenMDSQueue));
ThreadAll[0].Start();
}
// 這個例子有二個Thread , Main Thread 和 Linten Message Queue Thread
// 當Message Queeu Thread想改變Main Thread的資料時,要使用delegate的方式來達到目的
private delegate void InvokeUpdateState_forHashtable(System.Collections.Hashtable strHashtable);
private void setValueTable(System.Collections.Hashtable strHashtable)
{
if (this.InvokeRequired)
{
this.Invoke(new InvokeUpdateState_forHashtable(this.setValueTable), new object[] { strHashtable });
}
else
{
this.strHashtable_value = strHashtable;
}
}
C# Gargabe 觀念整理
CLR(Common Language Runtime) |