.NET Remoting程序开发入门篇(五)
| public class ServerObject:MarshalByRefObject { public ServerObj() { throw new System.NotImplementedException(); } public Person GetPersonInfo(string name,string sex,int age) { throw new System.NotImplementedException(); } } |
比較客戶端和服務器端,客戶端的方法GetPersonInfo(),沒有具體的實現細節,只是拋出了一個異常?;蛘咧苯訉懮险Z句return null,照樣OK。我們稱客戶端的這個類為遠程對象的替代類。
3、利用配置文件實現
前面所述的方法,于服務器uri、端口、以及激活模式的設置是用代碼來完成的。其實我們也可以用配置文件來設置。這樣做有個好處,因為這個配置文件是Xml文檔。如果需要改變端口或其他,我們就不需要修改程序,并重新編譯,而是只需要改變這個配置文件即可。 (1) 服務器端的配置文件:
| <configuration> <system.runtime.remoting> <application name="ServerRemoting"> <service> <wellknown mode="Singleton" type="ServerRemoteObject.ServerObject" objectUri="ServiceMessage"/> </service> <channels> <channel ref="tcp" port="8080"/> </channels> </application> </system.runtime.remoting> </configuration> |
如果是客戶端激活模式,則把wellknown改為activated,同時刪除mode屬性。
把該配置文件放到服務器程序的應用程序文件夾中,命名為ServerRemoting.config。那么前面的服務器端程序直接用這條語句即可:
RemotingConfiguration.Configure("ServerRemoting.config");
(2) 客戶端配置文件
如果是客戶端激活模式,修改和上面一樣。調用也是使用RemotingConfiguration.Configure()方法來調用存儲在客戶端的配置文件。
配置文件還可以放在machine.config中。如果客戶端程序是web應用程序,則可以放在web.config中。
4、啟動/關閉指定遠程對象
Remoting中沒有提供類似UnregisterWellKnownServiceType()的方法,也即是說,一旦通過注冊了遠程對象,如果沒有關閉通道的話,該對象就一直存在于通道中。只要客戶端激活該對象,就會創建對象實例。如果Remoting傳送的只有一個遠程對象,這不存在問題,關閉通道就可以了。如果傳送多個遠程對象呢?要關閉指定的遠程對象應該怎么做?關閉之后又需要啟動又該如何?
我們注意到在Remoting中提供了Marshal()和Disconnect()方法,答案就在這里。Marshal()方法是將MarshalByRefObject類對象轉化為ObjRef類對象,這個對象是存儲生成代理以與遠程對象通訊所需的所有相關信息。這樣就可以將該實例序列化以便在應用程序域之間以及通過網絡進行傳輸,客戶端就可以調用了。而Disconnect()方法則將具體的實例對象從通道中斷開。
方法如下:
首先注冊通道:
| TcpChannel channel = new TcpChannel(8080); ChannelServices.RegisterChannel(channel); |
接著啟動服務:
先在服務器端實例化遠程對象。
| ServerObject obj = new ServerObject(); |
然后,注冊該對象。注意這里不用RemotingConfiguration.RegisterWellKnownServiceType(),而是使用RemotingServices.Marshal():
| ObjRef objrefWellKnown = RemotingServices.Marshal(obj, "ServiceMessage"); |
如果要注銷對象,則:
| RemotingServices.Disconnect(obj); |
要注意,這里Disconnect的類對象必須是前面實例化的對象。正因為此,我們可以根據需要創建指定的遠程對象,而關閉時,則Disconnect之前實例化的對象。
至于客戶端的調用,和前面WellKnown模式的方法相同,仍然是通過Activator.GetObject()來獲得。但從實現代碼來看,我們會注意到一個問題,由于服務器端是顯式的實例化了遠程對象,因此不管客戶端有多少,是否相同,它們調用的都是同一個遠程對象。因此我們將這個方法稱為模擬的SingleTon模式。
客戶端激活模式
我們也可以通過Marshal()和Disconnect()來模擬客戶端激活模式。首先我們來回顧“遠程對象元數據相關性”一節,在這一節中,我說到采用設計模式的“抽象工廠”來創建對象實例,以此用SingleCall模式來模擬客戶端激活模式。在仔細想想前面的模擬的SingleTon模式。是不是答案就將呼之欲出呢?
在“模擬的SingleTon”模式中,我們是將具體的遠程對象實例進行Marshal,以此讓客戶端獲得該對象的引用信息。那么我們換一種思路,當我們用抽象工廠提供接口,工廠類實現創建遠程對象的方法。然后我們在服務器端創建工廠類實例。再將這個工廠類實例進行Marshal。而客戶端獲取對象時,不是獲取具體的遠程對象,而是獲取具體的工廠類對象。然后再調用CreateInstance()方法來創建具體的遠程對象實例。此時,對于多個客戶端而言,調用的是同一個工廠類對象;然而遠程對象是在各個客戶端自己創建的,因此對于遠程對象而言,則是由客戶端激活,創建的是不同對象了。
當我們要啟動/關閉指定對象時,只需要用Disconnet()方法來注銷工廠類對象就可以了。
六、小結
Microsoft.Net Remoting真可以說是博大精深。整個Remoting的內容不是我這一篇小文所能盡述的,更不是我這個Remoting的初學者所能掌握的。王國維在《人間詞話》一書中寫到:古今之成大事業大學問者,必經過三種境界。“昨夜西風凋碧樹,獨上高樓,望盡天涯路?!贝说谝痪辰缫?。“衣帶漸寬終不悔,為伊消得人憔悴。”此第二境界也。“眾里尋他千百度,驀然回首,那人卻在燈火闌珊處?!贝说谌辰缫?。如以此來形容我對Remoting的學習,還處于“獨上高樓,望盡天涯路”的時候,真可以說還未曾登堂入室。
或許需得“衣帶漸寬”,學得Remoting“終不悔”,方才可以“驀然回首”吧。
總結
以上是生活随笔為你收集整理的.NET Remoting程序开发入门篇(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 删除MSI包垃圾信息工具
- 下一篇: 【新媒体讨论】关联趋势和“就是不服”