您的位置:首页 > 其它

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

2005-06-01 15:02 495 查看

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



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

目的:[/b][/b]

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

优点:

这种交互关系的优点是:

完全异步:[/b][/b]

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

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

可扩展:[/b][/b]

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

可分布:[/b][/b]

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

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

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

HttpHandlers映射原理介绍:

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

public abstract class SoapReceiver : SoapPort, IHttpHandler

{

。。。

}

由于这一点,任何[/b] SoapReceiver [/b]或[/b] SendService [/b]类现在都能够在[/b] ASP.NET [/b]中配置为[/b] HTTP [/b]处理程序。[/b]通过在 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消息,那么SoapReceiver的Receive回调函数将被调用

-->

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

</httpHandlers>

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

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

静态的哈希表和HTTP终结点

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

Web Service异步实现模式

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

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

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

第二步,实现异步[/b]Web Service[/b]的[/b]BeginGetReceive[/b]方法:[/b][/b]

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

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

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

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

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

返回值必须为 IAsyncResult 类型。

第三步,实现异步[/b]Web Service[/b]的[/b]EndGetReceive[/b]方法:[/b][/b]

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

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

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

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

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

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

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

第五步,调用者收到回调后,就调用我们[/b]Web Service[/b]的[/b]EndGetReceive[/b]方法,从而从哈希表中拿到结果集。[/b][/b]

[/b]

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

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

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





图1 交互流程步骤说明

下面我们具体讲解一下:

首先,调用者请求Web Serviced的BeginGetReceive方法,这个方法再异步调用ProcessReceive方法它负责组装出一个SoapEnvelope[/b],并向Uri为

soap.tcp://hostname:port/yourreceivername

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

这里包含了图中的1,2,3三步:

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

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

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

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

这里包含了图中的4,5,6三步:

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

编写者:郑昀@UltraPower
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐