Remoting編程知識二
來源:互聯網
上載者:User
編程 Remoting進階知識
一、 如何使用IIS作為啟用代理
.NET Remoting和DCOM之間的一個區別是前者不支援自動啟動並執行伺服器處理序。需要人工啟動伺服器處理序來註冊用來遠程啟用的類和監聽請求。而對於DCOM,當遠程用戶端調用CoCreateInstanceEx或者其他啟用API時,會自動運行伺服器處理序。
.NET remoting 提供了兩種方法來避免人工啟動伺服器。第一個是將伺服器應用程式當做一個服務來實現。可以編寫一個從
System.ServiceProcess.Service派生的服務,重載其中關鍵的需方法例如OnStart和OnStop。將伺服器當做一個服務來實現的好處是你可以配置該服務以便系統啟動時能自動運行該服務。
第二個方法是使用IIS作為啟用代理。IIS本身就是一個服務,在大多數Web Servers運行時會一直啟動。而且IIS能夠通過使用.NET Remoting機制來響應用戶端啟用物件的請求。使用IIS有以下幾個好處:
1、不再需要編寫一個用來註冊可遠程化的類和監聽連接埠的伺服器,IIS就是伺服器。
2、可以使用IIS鑒別遠程調用者,也可以使用SSL來保護資料。
3、可以使用IIS來管理連接埠。如果在一個機器上部署了兩個傳統的應用程式伺服器,則需要你來保證這兩個伺服器使用不同的連接埠。使用IIS作為宿主,則IIS可以選擇連接埠,這樣可以簡化發布和管理。
IIS支援伺服器端啟用物件和用戶端啟用物件。可以使用程式註冊(在Global.asax中),也可以使用聲明註冊(在Web.config中)。
1、伺服器端啟用物件
下面的Web.config註冊了使用IIS啟用的Clock類:
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="Clock, ClockServer" objectUri="Clock.rem" />
</service>
</application>
</system.runtime.remoting>
</configuration>
注意Clock的URI:Clock.rem。使用IIS註冊的URI必須以.rem或者.soap結束,因為該擴充對應到IIS原資料中的Aspnet_isapi.dll和Machine.config中的.NET remoting 子系統。
使用IIS啟用物件都是通過HTTP通道來與用戶端進行通訊。用戶端必須註冊HTTP通道。下面是一個用戶端如何建立一個Clock執行個體,假設Clock在本地機器上一個叫MyClock的虛擬目錄中。
HttpClientChannel channel = new HttpClientChannel ();
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownClientType
(typeof (Clock),"http://localhost/MyClock/Clock.rem");
Clock clock = new Clock ();
注意伺服器和用戶端都沒有指定連接埠,IIS選擇該連接埠
2、用戶端啟用物件
Web.config檔案註冊註冊一個用戶端啟用物件Clock
<configuration>
<system.runtime.remoting>
<application>
<service>
<activated type="Clock, ClockServer" />
</service>
</application>
</system.runtime.remoting>
</configuration>
下面是用戶端的寫法(依然假設Clock在本地機器MyClock虛擬目錄中):
HttpClientChannel channel = new HttpClientChannel ();
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterActivatedClientType
(typeof (Clock), "http://localhost/MyClock");
Clock clock = new Clock ();
注意:使用IIS必須在虛擬目錄中有一個可遠程化的類,而且必須把 Web.config放在單獨的虛擬目錄中(例如MyClock),把DLL放在bin子目錄中(MyClock\bin)。
二、 如何通過HTTP通道傳遞二進位格式資料
使用IIS的一個缺點是只能使用HTTP通道。HTTP通道將調用封裝成SOAP訊息,這樣會增加訊息的長度。IIS只支援HTTP通道,但它並不要求使用將通道調用封裝成SOAP訊息。預設情況下,HTTP使用SOAP,因為它使用SoapClientFormatterSinkProvide和
SoapServerFormatterSinkProvider來作為序列化和還原序列化訊息的格式。可以使用BinaryClientFormatterSinkProvider和
BinaryServerFormatterSinkProvder來替換它們。二進位訊息可以跟好的利用網路頻寬。
下面的Web.config檔案註冊了一個可以被IIS啟用的Clock,它使用二進位替換了預設的SOAP格式。
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="SingleCall" type="Clock, ClockServer"
objectUri="Clock.rem" />
</service>
<channels>
<channel ref="http server">
<serverProviders>
<formatter ref="binary" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
用戶端寫法如下:
HttpClientChannel channel = new HttpClientChannel
("HttpBinary", new BinaryClientFormatterSinkProvider ());
ChannelServices.RegisterChannel (channel);
RemotingConfiguration.RegisterWellKnownClientType
(typeof (Clock), "http://localhost/MyClock/Clock.rem");
Clock clock = new Clock ();
當使用設定檔時,寫法為:
RemotingConfiguration.Configure ("Client.exe.config");
Clock clock = new Clock ();
設定檔內容如下:
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown type="Clock, ClockServer"
url="http://localhost/MyClock/Clock.rem" />
</client>
<channels>
<channel ref="http client">
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
使用相同的方法,你也可以在TCP通道中使用SOAP格式封裝訊息。你甚至可以將自己的格式化方法插入到現有的通道中。
三、 如何使用事件和代理
假設你建立了一個Clock 類,包括一個NewHour事件,代碼如下:
public delegate void NewHourHandler (int hour);
public class Clock : MarshalByRefObject
{
public event NewHourHandler NewHour;
...
}
在IIS上使用的Web.config檔案如下:
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="Singleton" type="Clock, ClockServer"
objectUri="Clock.rem" />
</service>
<channels>
<channel ref="http" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
注意ref屬性,http值使得two-way HttpCannel代替了one-way HttpServerChannel。
用戶端寫法如下:
RemotingConfiguration.Configure ("Client.exe.config");
Clock clock = new Clock ();
clock.NewHour += new NewHourHandler (OnNewHour);
.
.
.
public void OnNewHour (int hour)
{
// NewHour event received
}
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown type="Clock, ClockServer"
url="http://localhost/MyClock/Clock.rem" />
</client>
<channels>
<channel ref="http" port="0" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
用戶端也註冊了一個two-way HttpChannel,並且指定連接埠號碼為0。0值使得通道監聽回調,當然也可以允許.NET架構來選擇連接埠數。
四、 如何非同步呼叫一個可遠程化對象
預設情況下,,調用遠程對象是同步的。