解决异步响应问题的一种方法是利用一张静态查询表(static lookup table)将每个响应同某个远程服务器映射起来。换句话说,根据请求里的某个字段(例如客户id),我们就能够在数据库里查到响应服务器,并将应该送出的消息送达该服务器。这种方法的一个不足之处是:它会将对某个用户的所有请求都映射到特定的远程服务器上。但是,你可以创造一个更加动态的解决方案。
这个解决方案是动态的,因为它允许每个请求对应不同的响应服务器。事实上,它让请求的发起者来控制响应的去向,而不是利用查询表。为了帮助描述这个解决方案,我们会用到Web服务描述语言(Web Services Description Language,WSDL)里的描述,如Listing 1所示。
Listing 1:
dynamicasync.wsdl
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions name="DynamicAsynchronousServer"
xmlns="urn:schaffner.net:wsdl:dynamicasync"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="urn:schaffner.net:wsdl:dynamicasync">
<wsdl:types>
<xsd:schema
targetNamespace="urn:schaffner.net:wsdl:dynamicasync">
<xsd:element
name="key" type="xsd:string"/>
<xsd:element
name="wsdlurl" type="xsd:string"/>
<xsd:element
name="data" type="xsd:string"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="requestSoapOut"/>
<wsdl:message name="requestSoapIn">
<wsdl:part name="key"
element="key"/>
<wsdl:part name="wsdlurl"
element="wsdlurl"/>
<wsdl:part name="data"
element="data"/>
</wsdl:message>
<wsdl:message name="responseSoapOut"/>
<wsdl:message name="responseSoapIn">
<wsdl:part name="key"
element="key"/>
<wsdl:part name="data"
element="data"/>
</wsdl:message>
<wsdl:portType name="DynamicAsynchronousServerSOAP">
<wsdl:operation name="request">
<wsdl:input
name="requestInput" message="requestSoapIn"/>
</wsdl:operation>
<wsdl:operation name="response">
<wsdl:input
name="responseInput" message="responseSoapIn"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DynamicAsynchronousServerSOAPSOAP"
type="DynamicAsynchronousServerSOAP">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="request">
<soap:operation
style="document" soapAction="urn:schaffner.net:wsdl:dynamicasync/request"/>
<wsdl:input
name="requestInput">
<soap:body
use="literal"/>
</wsdl:input>
</wsdl:operation>
<wsdl:operation name="response">
<soap:operation
style="document" soapAction="urn:schaffner.net:wsdl:dynamicasync/response"/>
<wsdl:input
name="responseInput">
<soap:body
use="literal"/>
</wsdl:input>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DynamicAsynchronousServerSOAP">
<wsdl:port name="DynamicAsynchronousServerSOAPSOAPPort"
binding="DynamicAsynchronousServerSOAPSOAP">
<soap:address
location="http://www.schaffner.net/SOAP/DynamicAsync"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
首先,你会注意到在这个描述里定义了两项基本的操作。第一项操作叫做request,它包含对Web服务作出的请求。第二项操作叫做response,它包含对这个Web服务所作出的请求的响应。第三个组件是binding address(URL),它会通知服务应该把请求和响应操作送往哪里。