[WSE]Web Service与Windows Service通过WSE2.0建立订阅/发布关系[更新版]

 

[WSE]Web ServiceWindows Service通过WSE2.0建立订阅/发布关系

 

编写者:郑昀@UltraPower
编写日期:2005-04-13
修改日期:2005-05

目的:

我们建立这种交互关系的目的是,在Web ServiceWindows Service(或者其他Windows应用)之间建立起一种稳固的可扩展的不受地域限制的交互关系。 

优点:

这种交互关系的优点是:

完全异步:

Web serviceWindows service/windows form都可以实现交互的异步性,也就说,二者的交互完全是通过delegateWSE2.0消息机制实现的,彼此依赖性降低,web service可以像一个二传手,不断地将用户发起的请求路由到后台服务,web service不用和windows service之间保持长连接;windows service处理请求完毕,就发送soap消息给web servicehttp endpoint

你甚至可以在使用wse2.0MSMQ transport来替代http/tcp channel作为底层通信。

可扩展:

这种SOAP消息很容易定制和扩展新的包头定义。

可分布:

由于webservicehttp endpoint地址可以随着web service发消息给后台服务,所以webservice部署在哪里无关紧要,都可以和windows service保持交互。Webservice是通过wse2.0中的WS_Addressing机制把消息路由给Windows service的,所以二者可以部署到不同的机器上,只需要改变webservice的配置文件即可,后台服务能够根据传过来的SOAP包中的ReplyTo字段获知应该如何给哪里的http终结点回传消息。

 

为什么Webservice要采用HTTP EndPoint来接收SOAP消息?

由于Web Service的执行身份受限,所以我们无法直接让Web Service申请作为一个SoapReceiver,而是通过下面的web.config定义来制定本虚拟目录的.ashx终结点,从而通过WS_AddressingWS_Messaging机制来完成Web ServiceWindows Service之间的订阅/发布机制。

 

HttpHandlers映射原理介绍

ASP.NET 中,可以通过IHttpHandler,将 SoapReceiver HTTP 信道进行集成。如果查看一下 SoapReceiver 的定义,您会注意到它实现了 IHttpHandler

public abstract class SoapReceiver : SoapPort, IHttpHandler

{

   。。。

}

由于这一点,任何 SoapReceiver SendService 类现在都能够在 ASP.NET 中配置为 HTTP 处理程序。通过在 web.config 文件的 httpHandlers 部分添加一个新的映射,用户能够配置 http 处理程序。web.config 项将把 verb/path 组合映射到 SoapReceiver 类型:

首先,我们通过在web service的配置文件web.config中,加入如下示范片断:

<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>

<system.web>

<httpHandlers>

        <!-- 为了让我们的WebService能够接收到来自于后台侦听服务的SOAP消息

             我们让WebService继承自SoapReceiver,并实现了void Receive(SoapEnvelope envelope)

             这样exe通过向

             new Uri("http://"+ System.Net.Dns.GetHostName() + "/MyService/GetReceiver.ashx")

             发送SOAP消息,那么SoapReceiverReceive回调函数将被调用

        -->

      <add type="MyWebService.MyInterface" path="GetReceiver.ashx" verb="*" />

</httpHandlers>

把这组代码放到适当的位置,将针对每条输入此虚拟目录并指向 GetReceiver.ashx 的消息而调用 MyService。现在我们不必担心通过调用 SoapReceiver.Add 来配置 SoapReceiverSoapService,因为 ASP.NET 本质上代替您完成了此任务。

如果Windows Service通过SoapSender,就可以把消息发送到我们定义的 HTTP 终结点 (http://localhost/MyService/GetReceiver.ashx),它与使用 TCP 信道接收SOAP消息的工作方式相同,只是现在它通过 HTTP 进行通讯。

静态的哈希表和HTTP终结点

我们在webservice中加上几个静态的哈希表,存储了客户端的回调函数以及其他信息,还有对应的查询请求等,相当于保存了会话状态,从而能够在这些哈希表的帮助下完成与Windows服务之间的异步交互,以及与客户端调用者之间的异步交互。

 

Web Service异步实现模式

实现异步 XML Web services 方法应遵循 .NET Framework 异步设计模式。

第一步,将我们的异步 XML Web services 方法GetReceive拆分成两个方法。

每个方法都有相同的基名称,即一个以 Begin 开始,另一个以 End 开始;

 

第二步,实现异步Web ServiceBeginGetReceive方法:

BeginGetReceive 方法的参数列表包含方法功能的所有 in by reference 参数,以及追加到结尾的两个参数。

By reference 参数作为 in 参数列出。

倒数第二个参数必须为 AsyncCallbackAsyncCallback 参数允许客户端提供委托,在方法完成时将调用该委托。

当一个异步 XML Web services 方法调用另一个异步方法时,此参数可被传递到该方法的倒数第二个参数。

最后一个参数是 ObjectObject 参数允许调用方为方法提供状态信息。当一个异步 XML Web services 方法调用另一个异步方法时,此参数将被传递到该方法的最后一个参数。

返回值必须为 IAsyncResult 类型。

 

第三步,实现异步Web ServiceEndGetReceive方法:

EndGetReceive 方法的参数列表包含 IAsyncResult 参数,此参数后面带有特定于该方法功能的任意 out by reference 参数。

返回值类型与异步 XML Web services 方法的返回值类型相同。

By reference 参数作为 out 参数列出。

 

我们与一般的异步Web Service不同之处在于,BeginGetReceive 方法中又调用的

IAsyncResult arr = prcDelegate.BeginInvoke(null, callback, asyncState);

方法是类内部定义的“ProcessReceive”函数,它实际上还是一个异步处理消息过程,它只是把要处理的查询请求用SoapSender发送给后台服务,之后就返回,不再等待。

 

第四步,等到后台服务把结果发送给本Web ServiceHTTP终结点,我们再把结果都存储在哈希表中,然后回调调用者。

 

第五步,调用者收到回调后,就调用我们Web ServiceEndGetReceive方法,从而从哈希表中拿到结果集。

 

上面描述的流程如下一节的图片所示。

Web Service—Windows Service/Form的订阅/发布关系

由于Web Service运行的身份是ASP.NET用户,而SoapReceiver.Add方法对执行权限要求较高,所以我们采用HTTP终结点的方式,再加上几个静态的哈希表,从而完成了与后台侦听服务之间的异步交互,以及与客户端调用者之间的异步交互。


1 交互流程步骤说明

下面我们具体讲解一下:

首先,调用者请求Web ServicedBeginGetReceive方法,这个方法再异步调用ProcessReceive方法它负责组装出一个SoapEnvelope,并向Uri

soap.tcp://hostname:port/yourreceivername

的目标EndPoint,用SoapSender.Send发送这个SoapEnvelope。一方面用于通知订阅关系,另一方面传递了各项参数,以及预先生成的GUID。之后就将处理权返回调用者。

这里包含了图中的123三步:

其次,正在监听的侦听服务收到了消息,进行处理:

添加这个订阅者的各种信息到静态哈希表;

利用I/O完成端口异步执行各种任务;

把结果集或者错误信息通过Web Service HTTP终结点通知订阅者。

这里包含了图中的456三步:

 

最后,订阅者Web Service收到通知后,通知客户端调用者的回调函数来取回结果集,从而将结果集或者错误原因返回给客户端。

 

编写者:郑昀@UltraPower

posted @ 2005-06-01 15:02  旁观者  阅读(2135)  评论(4编辑  收藏  举报