摘要:.NET Remoting是一種允許對象通過應(yīng)用程序域與另一對象進(jìn)行交互的框架,與Socket直接通信以及ASP.NET WEB服務(wù)相比有著自身明顯的特點(diǎn),在一定條件下有著處理事件速度快、開發(fā)難度相對較低的優(yōu)點(diǎn),本文主要說明了高效應(yīng)用.NET Remoting實(shí)現(xiàn)遠(yuǎn)程事件處理的技術(shù)方案及關(guān)鍵技術(shù),以提高分布式系統(tǒng)的整體性能。
關(guān)鍵詞:Remoting;遠(yuǎn)程事件處理;消息發(fā)送
1 Remoting基礎(chǔ)
Remoting就是DCOM的一種升級,通過通道(channel)來實(shí)現(xiàn)兩個(gè)應(yīng)用程序域之間對象的通信,原理如圖1所示。
Remoting中主要包括HTTP和TCP兩種通道,HTTP通道默認(rèn)使用SOAP格式序列化消息對象,具有更好的互操作性,而TCP通道則默認(rèn)采用二進(jìn)制格式,具有更高的傳輸性能,因此,在局域網(wǎng)內(nèi)的應(yīng)用常選擇TCP通道,而在需要穿越防火墻的情況下,則選擇HTTP通道。
01
在Remoting中,遠(yuǎn)程對象的激活分為服務(wù)器端激活和客戶端激活兩大類,其中服務(wù)器端激活又稱為WellKnow方式,因?yàn)榉?wù)器應(yīng)用程序在激活對象實(shí)例之前會(huì)在已公布的URL上發(fā)布對應(yīng)類型,并為此類型配置一個(gè)WellKnow對象。服務(wù)器端激活方式中又可以分成SingleTon模式和SingleCall模式兩種,其中SingleTon模式中有狀態(tài)模式,Remoting將為所有客戶端建立同一個(gè)對象實(shí)例;SingleCall模式是無狀態(tài)模式,Remoting會(huì)為每一個(gè)客戶端建立一個(gè)遠(yuǎn)程對象實(shí)例??蛻舳思せ钅J絼t在激活每個(gè)對象實(shí)例時(shí),為每個(gè)客戶端激活的類型給定一個(gè)URL。
Remoting傳遞的對象是通過引用的方式實(shí)現(xiàn)的,因此所傳遞的遠(yuǎn)程對象類必須繼承MarshalByRefObject。MarshalByRefObject是通過使用代理交換消息來跨越應(yīng)用程序域邊界進(jìn)行通信的對象的基類。服務(wù)器端運(yùn)行過程中,一般通過注冊通道、注冊遠(yuǎn)程對象和注銷通道三個(gè)步驟完成工作;而客戶端則主要完成注冊通道和獲得遠(yuǎn)程對象兩件事。
2 分布式應(yīng)用技術(shù)
Remoting技術(shù)在分布式處理程序中的應(yīng)用中,通常由遠(yuǎn)程對象、服務(wù)端、客戶端三部分組成,常用的事件處理形式包括:服務(wù)端訂閱客戶端事件、客戶端訂閱服務(wù)端事件和客戶端訂閱客戶端事件三種,事件處理的實(shí)現(xiàn)是Remoting在分布式應(yīng)用中的難點(diǎn)。
服務(wù)器端訂閱客戶端事件是由客戶端發(fā)送消息,服務(wù)端捕捉消息然后處理對應(yīng)事件??蛻舳擞嗛喎?wù)端事件,則是由服務(wù)端發(fā)送消息,所有客戶端都捕獲消息,激發(fā)事件,形成廣播形式的消息發(fā)送和捕獲方式??蛻舳擞嗛喛蛻舳耸录悄硞€(gè)客戶端發(fā)出消息,其他客戶端捕獲消息,激發(fā)事件。所有事件處理形式中,真正包含事件的都是遠(yuǎn)程對象。
在分布式應(yīng)用中,目前大部分實(shí)時(shí)數(shù)據(jù)處理系統(tǒng)中,都必須實(shí)現(xiàn)服務(wù)端訂閱客戶端事件,當(dāng)客戶端需要向服務(wù)端發(fā)送消息,要求服務(wù)端處理相關(guān)數(shù)據(jù)或事件時(shí),只需要通過已激活遠(yuǎn)程對象發(fā)送消息,則服務(wù)端將接收到消息,并能自動(dòng)調(diào)用已注冊好的事件處理程序,啟動(dòng)事件處理流程,再把處理的結(jié)束發(fā)送回客戶端,則客戶端與服務(wù)端完成一次消息傳遞和事件處理,并且調(diào)用服務(wù)端完成業(yè)務(wù)及數(shù)據(jù)的處理。通過這種方式實(shí)現(xiàn)客戶端對服務(wù)端功能的調(diào)用比簡單地通過套接字進(jìn)行消息的傳遞要方便很多,并能更好地保證系統(tǒng)質(zhì)量。
3 服務(wù)端訂閱客戶端事件實(shí)現(xiàn)
簡單的服務(wù)端訂閱客戶端事件的實(shí)現(xiàn)并不特別困難,但必須注意,客戶端由于程序代碼可能需要部署到客戶計(jì)算機(jī),因此對于關(guān)鍵性業(yè)務(wù)處理的類的相關(guān)代碼不應(yīng)該被部署到客戶端,才能提高系統(tǒng)的安全性,以防止中間代碼被反編譯而導(dǎo)致關(guān)鍵機(jī)密被破解。
為保證客戶端與服務(wù)端能正常進(jìn)行通信,必須定義客戶端與服務(wù)端之間的接口能統(tǒng)一,因頁設(shè)計(jì)一個(gè)遠(yuǎn)程對象的公共接口,此接口僅定義通信接口,而接口中各消息的處理(也就是接口中的方法),只在處理業(yè)務(wù)的遠(yuǎn)程對象類中實(shí)現(xiàn),這些處理業(yè)務(wù)的遠(yuǎn)程對象類將被設(shè)計(jì)到獨(dú)立的一個(gè)程序集中,此程序集被不被引用到客戶端系統(tǒng)中,僅會(huì)引用到服務(wù)端,以實(shí)現(xiàn)業(yè)務(wù)的處理,也就是完成對客戶端消息的處理。
遠(yuǎn)程對象的公共接口(RemoteICommon.dll):
public delegate void MessageEventHandler(string message);
public interface IBusiness
{
void SendMessage(string message);
}
具體處理傳真業(yè)務(wù)的遠(yuǎn)程對象類(RemoteObj)程序集中,引用遠(yuǎn)程對象公共接口程序集,實(shí)現(xiàn)遠(yuǎn)程對象類:
public class Business:MarshalByRefObject, IBusiness
{
public static event MessageEventHandler MessageSendedEvent;
public void SendMessage (string message)
{
if (MessageSendedEvent!= 1)
{
MessageSendedEvent (fax);
}
}
public override object InitializeLifetimeService()
{
return 1;
}
}
其中遠(yuǎn)程對象中的事件類型是公共接口中定義的委托類型,并且實(shí)現(xiàn)了接口中的方法,這個(gè)方法的實(shí)現(xiàn)就是開始啟動(dòng)客戶端消息處理的地方,而覆蓋MarshalByRefObject接口中的InitializeLifetimeService,并返回1則可以使遠(yuǎn)程對象的生命周期為無限大。
在服務(wù)端中,引用遠(yuǎn)程對象類所在的程序集,并且在服務(wù)端啟動(dòng)服務(wù)過程中注冊通道和遠(yuǎn)程對象,最后再注冊事件處理程序,方法為:
BinaryServerFormatterSinkProvider serverProvider = new
BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new
BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props[\"port\"] = 8000;/*端口*/
HttpChannel channel = new HttpChannel(props, clientProvider, serverProvider);
System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(channel);
remotingServer = new Business();
ObjRef objref = RemotingServices.Marshal(remotingServer, remoteURL);
remotingServer. MessageSendedEvent += new Message
EventHandler(OnMessageSended);
客戶端僅引用遠(yuǎn)程對象公共接口程序集(RemoteICommon.dll),在激活遠(yuǎn)程對象后,通過調(diào)用遠(yuǎn)程對象的方法,完成向服務(wù)端發(fā)送相應(yīng)的消息,方法為:
IBusiness remotingAgent = (ITraderBusiness)Activator.GetObject(typeof(ITraderBusiness), \"http://serverIP:port/remoteURL\");
remotingAgent. SendMessage(“發(fā)送的消息內(nèi)容”);
4 結(jié)論
應(yīng)用Remoting技術(shù)實(shí)現(xiàn)遠(yuǎn)程事件處理比直接應(yīng)用Socket發(fā)送數(shù)據(jù)的方式,能較大程序的降低開發(fā)技術(shù)難度,減少開發(fā)工作量,提高系統(tǒng)穩(wěn)定性;與ASP.NET WEB服務(wù)相比,當(dāng)Remoting應(yīng)用TCP通道時(shí),系統(tǒng)每秒處理事務(wù)的數(shù)量比ASP.NET WEB服務(wù)要高,而且Remoting應(yīng)用HTTP通道時(shí),系統(tǒng)每秒處理事務(wù)的數(shù)量則比ASP.NET WEB服務(wù)要低很多;綜合各種技術(shù)方案的特點(diǎn),在系統(tǒng)條件滿足時(shí),應(yīng)優(yōu)先選擇Remoting 在 TCP 上使用二進(jìn)制序列化方案實(shí)現(xiàn)遠(yuǎn)程事件處理。
參考文獻(xiàn)
[1]Ingo Rammer.Advanced .NET Remoting.New York:Springer-Verlag New York Inc.2008.
[2]微軟公司.基于C#的.NET Framework程序設(shè)計(jì)[M].北京:高等教育出版社,2004.
[3]微軟公司.組件應(yīng)用程序設(shè)計(jì)——COM+應(yīng)用程序設(shè)計(jì)[M].北京:高等教育出版社,2004.
[4]微軟公司.基于.NET的需求分析和解決方案設(shè)計(jì)[M].北京:高等教育出版社,2004.
[5]微軟公司.基于C#的Windows應(yīng)用程序設(shè)計(jì)[M].北京:高等教育出版社,2004.