[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终结点的方式,再加上几个静态的哈希表,从而完成了与后台侦听服务之间的异步交互,以及与客户端调用者之间的异步交互。

%E8%BE%83%E4%B8%BA%E9%80%9A%E7%94%A8%E7%

交互流程步骤说明

下面我们具体讲解一下:

首先,调用者请求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

目录
相关文章
|
2月前
|
Java Unix 应用服务中间件
使用java service wrapper把windows flume做成服务
使用java service wrapper把windows flume做成服务
|
6月前
|
关系型数据库 MySQL Windows
windows安装mysql报错Remove of the Service Denied!
windows安装mysql报错Remove of the Service Denied!
|
1月前
|
Windows
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
Windows Server 各版本搭建 Web 服务器实现访问本地 Web 网站(03~19)
57 2
|
5月前
|
消息中间件 数据安全/隐私保护 Windows
windows下RabbitMQ安装后,无法进入web管理页面问题
windows下RabbitMQ安装后,无法进入web管理页面问题
140 1
|
1月前
|
存储 缓存 算法
关于 Service Worker 和 Web 应用对应关系的讨论
关于 Service Worker 和 Web 应用对应关系的讨论
13 0
|
2月前
|
Java API Apache
Apache CXF生成WebService的客户端
Apache CXF生成WebService的客户端
|
6月前
|
JSON 安全 API
使用 ABAP sproxy 事务码生成的 Proxy 消费 Web Service
使用 ABAP sproxy 事务码生成的 Proxy 消费 Web Service
56 0
|
2月前
|
XML 网络架构 数据格式
Ruby 教程 之 Ruby Web Service 应用 - SOAP4R 2
Ruby Web Service 应用 - SOAP4R
24 5
|
2月前
|
XML Linux 网络架构
Ruby 教程 之 Ruby Web Service 应用 - SOAP4R 1
Ruby Web Service 应用 - SOAP4R
23 3
|
4月前
|
Java 数据库连接 Apache
SpringBoot整合CXF实现WebService
SpringBoot整合CXF实现WebService
126 0