由於Web Service的執行身份受限,所以我們無法直接讓Web Service申請作為一個SoapReceiver,而是通過下面的web.config定義來制定本虛擬目錄的.ashx終結點,從而通過WS_Addressing和WS_Messaging機制來完成與後台偵聽服務之間的訂閱/發佈機制。
<configuration>
<configSections>
<section name="microsoft.web.services"
type="Microsoft.Web.Services.Configuration.WebServicesConfiguration,
Microsoft.Web.Services, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35" />
</configSections>
原理介紹:
除了進程內與 TCP 通訊機制,還可以在 ASP.NET 中將 SoapReceivers 與 HTTP 管道進行集成。如果查看一下 SoapReceiver 的定義,您會注意到它實現了 IhttpHandler:
public abstract class SoapReceiver : SoapPort, IHttpHandler
{
。。。
}
由於這一點,任何 SoapReceiver 或 SendService 類現在都能夠在 ASP.NET 中配置為 HTTP 處理程序。通過在 web.config 文件的 httpHandlers 部分添加一個新的映射,用戶能夠配置 http 處理程序。web.config 項將把 verb/path 組合映射到 SoapReceiver 類型:
<system.web>
<httpHandlers>
<!-- 為了讓我們的WebService能夠接收到來自於後台偵聽服務的SOAP消息
我們讓WebService繼承自SoapReceiver,並實現了void Receive(SoapEnvelope envelope),
這樣DLL通過向
new Uri("http://"+ System.Net.Dns.GetHostName() + "/MyService/GetReceiver.ashx")
發送SOAP消息,那麼SoapReceiver的Receive回調函數將被調用
-->
<add type="MyWebService.MyInterface" path="GetReceiver.ashx" verb="*" />
</httpHandlers>
把這組代碼放到適當的位置,將針對每條輸入此虛擬目錄並指向 GetReceiver.ashx 的消息而調用 MyService。現在我們不必擔心通過調用 SoapReceiver.Add 來配置 SoapReceiver/SoapService,因為 ASP.NET 本質上代替您完成了此任務。
如果更新客戶端以把消息發送到 HTTP 終結點 (http://localhost/MyService/GetReceiver.ashx),它會與使用 TCP 的工作方式相同,只是現在它通過 HTTP 進行通訊。
Web Service—後台偵聽服務訂閱關係
由於Web Service運行的身份是ASP.NET用戶,而SoapReceiver.Add方法對執行權限要求較高,所以我們採用HTTP終結點的方式,再加上幾個靜態的哈希表,從而完成了與後台偵聽服務之間的異步交互,以及與客戶端調用者之間的異步交互。
下面我們具體講解一下:
首先,調用者請求Web Serviced的BeginXXX方法,這個方法再異步調用ProcessXXX方法它負責組裝出一個SoapEnvelope,並向Uri為
soap.tcp://hostname:port/yourreceivername
的目標EndPoint,用SoapSender.Send發送這個SoapEnvelope。一方面用於通知訂閱關係,另一方面傳遞了各項參數,以及預先生成的GUID。之後就將處理權返回調用者。
這裡包含了圖中的1,2,3三步:
其次,正在監聽的偵聽服務收到了消息,進行處理:
添加這個訂閱者的各種信息到靜態哈希表;
利用I/O完成端口異步執行各種任務;
把結果集或者錯誤信息通過Web Service HTTP終結點通知訂閱者。
這裡包含了圖中的4,5,6三步:
最後,訂閱者Web Service收到通知後,通知客戶端調用者的回調函數來取回結果集,從而將結果集或者錯誤原因返回給客戶端。
編寫者:鄭昀@UltraPower
|
|