- UID
- 824598
|
一种消息处理器的的设计与实现
XML和简单对象访问协议(Simple Object Access Protocol,SOAP)带来了信息交换技术革命性的进步,极大地促进了分布式应用的发展。XML(Extensible Markup Language)即可扩展标记语言,它与HTML一样,都是SGML(Standard Generalized Markup Language,标准通用标记语言)。Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具。扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用。目前,在基于SOAP信息交换应用的集成化开发环境和工具中关于SOAP的技术对开发人员基本上是透明的,即屏蔽和隐藏了SOAP实现和处理的细节。深入了解SOAP消息的处理过程和SOAP处理器的工作机理,可以对分布式应用进行更加灵活地控制。
1 SOAP概述
简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。SOAP 消息基本上是从发送端到接收端的单向传输,但它们常常结合起来执行类似于请求 / 应答的模式。所有的 SOAP 消息都使用 XML 编码。一条 SOAP 消息就是一个包含有一个必需的 SOAP 的封装包,一个可选的 SOAP 标头和一个必需的 SOAP 体块的 XML 文档。
2 SOAP消息处理模型
2.1 SOAP的应用架构和消息处理模型框架
SOAP成功地解决了异构网络环境中的软件组件和应用程序之间进行可靠信息交换的难题。以Web Service为例,其SOAP RPC的应用架构如图1所示。一般开发环境都隐藏了SOAP消息处理的过程,这部分功能封装于由开发环境自动生成的客户端和服务器端的SOAP代理模块中,其中都使用了编译好的高层类库,用户据此难以探究其内部的处理细节。
实际上,客户端和服务器端的SOAP代理模块内部做了大量的处理工作。SOAP RPC的处理过程如图2所示。客户端模块按照Web Service使用接口要求的格式和规范,通过XML处理器将客户端的RPC调用编码成SOAP请求消息。SOAP请求消息中按规定封装了请求服务所必需的信息,借助传输协议传送到服务器端;服务器的传输协议监听器得到传输的内容,由服务器端的代理模块按照WSDL文档描述的Web Service接口的信息采用XML处理器对SOAP请求消息进行解析,提取出适当的信息,生成提供相应的Web服务的对象,调用请求的方法,得到服务程序的处理结果,再按WSDL文档的要求将服务处理结果生成SOAP响应消息,借助传输协议传回客户端;客户端的代理按照WSDL文档描述的信息解析SOAP响应消息,提取出适当的信息返回客户程序。在客户端和服务器端对SOAP消息进行串行化和反串行化期间,涉及到客户程序的数据类型与XML的类型系统XSD之间,以及XML的类型系统XSD与服务程序的数据类型之间的相互映射,还有对象参数的序列化和反序列化工作。
当SOAP与HTTP绑定时,服务器端的消息监听可以采用ASP或ISAPI处理方式。
SOAP消息的生成和解析工作与WSDL文档密切相关,只有遵照Web Service对应的WSDL文档中描述的信息格式,SOAP消息才能得到正确的、自动化的处理。
2.2 WSDL简介
WSDL是Web Service的描述语言,用于描述Web Service的服务,接口绑定等,它以一种XML模式来描述Web Service的接口。服务的使用方根据这些描述信息来理解如何使用服务。由于描述方法和格式具有统一的标准和规范,因此便于由机器来自动处理描述信息。实际上,很多开发环境就是由软件工具根据服务模块自动生成相应的WSDL文档。
在具体实现SOAP处理器的过程中需要编程访问WSDL文档。为使篇幅简洁,本文将采用MS SOAP TK 3.0中提供的WSDL文档模型对象接口(详情可参见MSTK3.0开发文档)来编程分析WSDL文档,即通过编程对象及其方法遍历文档中的元素,得到的接口描述信息用以处理SOAP消息。
3 实现SOAP处理器的功能
由图2所示的SOAP消息处理器的功能和过程架构,可以实现自行开发的SOAP处理器。
3.1 具体的实现模型
由于SOAP消息和WSDL文档都是基于XML格式的,所以代理的工作主要是分析和处理XML文档。可以根据SOAP消息封装格式、编码规则、RPC表示以及WSDL文档结构的协议规范,采用任一种XML解析器工具来处理SOAP和WSDL这类特殊的XML文档(如图2所示)。本文将采用MSTK3.0中的低层API来实现SOAP代理,处理过程反映了技术机理和细节。将准备实现的客户端和服务器端的SOAP代理类命名为mySoapClient和mySoapServer。其内部实现过程模型分别如图3和图4所示。
3.2 具体实现
下面采用VB6.0来实现mySoapClient类和mySoapServer类。
3.2.1 客户端SOAP代理
新建ActiveX DLL工程MyClientSoap,添加并引用Microsoft Soap Type Library v3.0。将以下代码加入mySoapClient类模块中。
Dim Port As IWSDLPort
Public Sub Initialize(ByVal WSDLFileName As String,
Optional ByVal ServiceName As String=″″,
Optional ByVal PortName As String=″″,
Optional ByVal WSMLFileName As String=″″)
Dim Fetched As Long
Dim WSDLReader As New WSDLReader30
′load WSDL file
WSDLReader.Load WSDLFileName,WSMLFileName
′get the service
Dim ServiceEnumerator As IEnumWSDLService,Service As IWSDLService
WSDLReader.GetSoapServices ServiceEnumerator
If ServiceName=″″Then
ServiceEnumerator.Next 1,Service,Fetched
Else
ServiceEnumerator.Find ServiceName,Service
End If
′get the port
Dim PortEnumerator As IEnumWSDLPorts
Service.GetSoapPorts PortEnumerator
If PortName=″″Then
PortEnumerator.Next 1,Port,Fetched
Else
PortEnumerator.Find PortName,Port
End If
End Sub
Public Invoke(ByVal OperationName As String,
ParamArray Parameter() As Variant) As Variant
′find the operation
Dim OperationEnumerator As IEnumWSDLOperations,
Operation As IWSDLOperation
Port.GetSoapOperations OperationEnumerator
OperationEnumerator.Find OperationName,Operation
′prepare request
Dim MapperEnumerator As IEnumSoapMappers,
Mapper As ISoapMapper
Operation.GetOperationParts MapperEnumerator
Dim Fetched As Long
MapperEnumerator.Next 1,Mapper,Fetched
Do While Fetched=1
If (Mapper.IsInput=smInput) Or (Mapper.IsInput=smInOut) Then
Mapper.ComValue=Parameter(Mapper.ParameterOrder)
End If
MapperEnumerator.Next 1,Mapper,Fetched
Loop
′construct the request message and send it.
′(that is,invoking the operation and getting result)
Dim Serializer As SoapSerializer30
Dim Connector As SoapConnector30
Set Connector=New HttpConnector30
Connector.ConnectWSDL Port
Connector.BeginMessageWSDL Operation
Set Serializer=New SoapSerializer30
Serializer.Init Connector.InputStream
Serializer.StartEnvelope
Serializer.StartBody
Operation.Save Serializer,True′writes the XML
Serializer.EndBody
Serializer.EndEnvelope
′load response
Dim SoapReader As New SoapReader30
SoapReader.Load Connector.OutputStream
Operation.Load SoapReader,False
′return the outgoing parameters and result
MapperEnumerator.Reset
MapperEnumerator.Next 1,Mapper,Fetched
Do While Fetched=1
If Mapper.IsInput=smOutput Then
If Mapper.VariantType=vbObject Then
Set Invoke=Mapper.ComValue
Else
Invoke=Mapper.ComValue
End If
ElseIf Mapper.IsInput=smInOut Then
Parameter(Mapper.ParameterOrder)=Mapper.ComValue
End If
MapperEnumerator.Next 1,Mapper,Fetched
Loop
End
将mySoapClient类实例化就成为客户端SOAP代理对象。mySoapClient类向外提供了二个可调用的接口:(1)Initialize方法利用WSDL文档中描述的Web Service接口消息来初始化客户端代理对象,用户还可指定要远程调用的Web Service的服务名称ServiceName和端口名称PortName。(2)Invoke方法向客户程序提供了使用Web Service的接口,用户只需提供Web Service中的方法名称和此方法的参数,就可以调用Web Service。
3.2.2 服务器端SOAP代理
新建ActiveX DLL工程MyServerSoap,并添加引用Microsoft Soap Type Library v3.0。
将以下代码加入mySoapServer类模块中。
Dim WSDLReader As WSDLReader30
Public Sub Initialize(ByVal WSDLFileName As String,ByVal WSMLFileName As String)
Set WSDLReader=New WSDLReader30
WSDLReader.SetProperty ″LoadOnServer″,True
WSDLReader.Load WSDLFileName,WSMLFileName
End Sub
Public Sub ProcessRequest(ByVal Request As IStream,ByVal Response As IStream)
Dim WSDLPort As IWSDLPort
Dim WSDLOperation As IWSDLOperation
Dim Serializer As New SoapSerializer30
Dim SoapReader As New SoapReader30
SoapReader.Load Request
WSDLReader.ParseRequest SoapReader,WSDLPort,
WSDLOperation
WSDLOperation.Load SoapReader,True
Serializer.Init Response
Serializer.StartEnvelope
WSDLOperation.ExecuteOperation SoapReader,Serializer
Serializer.StartBody
WSDLOperation.Save Serializer,False
Serializer.EndBody
Serializer.EndEnvelope
End Sub
编译后生成MyServerSoap.dll。将mySoapServer类实例化就成为服务器端SOAP代理对象。Initialize方法利用WSDL文档来初始化服务器端代理对象。ProcessRequest方法分析接收到的SOAP请求消息,调用相应的Web Service方法,将结果编码成SOAP响应消息回传。
以上详细剖析了SOAP消息的处理过程,设计实现了SOAP处理器。本文中实现代理类的代码还可进一步细化,甚至完全可以不引用MSTK3.0中的低层API类库,而采用XML解析器来编写SOAP处理器。由于篇幅所限,还有一些细节问题未能进一步展开探讨,如复杂数据类型的编码、SOAP头部的处理、错误的捕获和附件的处理等。本文已实现了SOAP处理器最重要的核心功能框架,用户可以在此基础上,增加调用附加功能的接口,这样可以实现功能更加丰富的SOAP处理器。
|
|
|