网络协议 20 - RPC 协议(上)- 基于XML的SOAP协议 (2)

    基于 XML 的最著名的通信协议就是SOAP了,全称简单对象访问协议(Simple Object Access Protocol)。它使用 XML 编写简单的请求和回复消息,并用 HTTP 协议进行传输。

    SOAP 将请求和回复放在一个信封里面,就像传递一个邮件一样。信封里面的信分抬头正文

POST /purchaseOrder HTTP/1.1 Host: Content-Type: application/soap+xml; charset=utf-8 Content-Length: nnn <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:Header> <m:Trans xmlns:m="http://www.w3schools.com/transaction/" soap:mustUnderstand="1">1234 </m:Trans> </soap:Header> <soap:Body xmlns:m="http://www.cnblog.com/perchaseOrder"> <m:purchaseOrder"> <order> <date>2019-01-08</date> <className> 板栗焖鸡 </className> <price>88</price> </order> </m:purchaseOrder> </soap:Body> </soap:Envelope>

    HTTP 协议我们学过,这个请求使用 POST 方法,发送一个格式为 application/soap + xml 的 XML 正文给 ,从而下一个单,这个订单封装在 SOAP 的信封里面,并且表明这是一笔交易(transaction),而且订单的详情都已经写明了。

协议约定问题

    接下来我们解决第二个问题,就是双方的协议约定是什么样的?

    因为服务开发出来是给陌生人用的,就像上面下单的那个 XML 文件,对于客户端来说,它如何知道应该拼装成上面的格式呢?这就需要对于服务进行描述,因为调用的人不认识你,所以没办法找到你,问你的服务应该如何调用。

    当然你可以写文档,然后放在官方网站上,但是你的文档不一定更新得那么及时,而且你也写的文档也不一定那么严谨,所以常常会有调试不成功的情况。因而,我们需要一种相对比较严谨的Web 服务描述语言,WSDL(Web Service Description Languages)。它也是一个 XML 文件。

    在这个文件中,要定义一个类型 order,与上面的 XML 对应起来。

<wsdl:types> <xsd:schema targetNamespace="http://www.example.org/cnblog"> <xsd:complexType> <xsd:element type="xsd:string"></xsd:element> <xsd:element type="xsd:string"></xsd:element> <xsd:element type="xsd:string"></xsd:element> <xsd:element type="xsd:int"></xsd:element> </xsd:complexType> </xsd:schema> </wsdl:types>

    接下来,需要定义一个 message 的结构。

<wsdl:message> <wsdl:part element="tns:order"></wsdl:part> </wsdl:message>

    接下来,应该暴露一个端口。

<wsdl:portType> <wsdl:operation> <wsdl:input message="tns:purchase"></wsdl:input> <wsdl:output message="......"></wsdl:output> </wsdl:operation> </wsdl:portType>

    然后,我们来编写一个 binding,将上面定义的信息绑定到 SOAP 请求的 body 里面。

<wsdl:binding type="tns:PurchaseOrderService"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding>

    最后,我们需要编写 service。

<wsdl:service> <wsdl:port binding="tns:purchaseOrderServiceSOAP"> <soap:address location="http://www.cnblog.com:8080/purchaseOrder" /> </wsdl:port> </wsdl:service>

    WSDL 还是有些复杂的,不过好在有工具可以生成。

    对于某个服务,哪怕是一个陌生人,都可以通过在服务地址后面加上“?wsdl”来获取到这个文件,但是这个文件还是比较复杂,比较难以看懂。不过好在也有工具可以根据 WSDL 生成客户端 Stub,让客户端通过 Stub 进行远程调用,就跟调用本地的方法一样。

服务发现问题

    最后解决第三个问题,服务发现问题。

    这里有一个UDDI(Universal Description, Discovery, and Integration),也即统一描述、发现和集成协议。它其实是一个注册中心,服务提供方可以将上面的 WSDL 描述文件,发布到这个注册中心,注册完毕后,服务使用方可以查找到服务的描述,封装为本地的客户端进行调用。

小结

原来的二进制 RPC 有很多缺点,格式要求严格,修改过于复杂,不面向对象,于是产生了基于文本的调用方式——基于 XML 的 SOAP;

SOAP 有三大要素:协议约定用 WSDL、传输协议用 HTTP、服务发现用 UDDL。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzzjp.html