基于XML的SOAP协议

    xiaoxiao2022-07-07  184

    ONC RPC 存在哪些问题

    ONC RPC将客户端要发送的参数,以及服务端要发送的回复,都压缩为一个二进制串,这样固然能够解决双方的协议约定问题,但是存在一定的不方便。 首先,需要双方的压缩格式完全一致,一点都不能差,一旦有少许的差错,多一位,少一位或者错一位,都可能无法解压缩,当然,我们可以用传输层的可靠性以及加入校验值等方式,来减少传输过程中的差错。 其次,协议修改不灵活,如果不是传输过程中造成的差错,而是客户端因为业务逻辑的改变,添加或者删除了字段,双方没有及时通知,或者线上系统没有及时升级,就会造成解压缩不成功。 因而,当业务发生改变,需要多传输一些参数或者少传输一些参数的时候,都需要及时通知对方,并且根据约定好的协议文件重新生成双方的Stub程序,这样灵活性比较差 除了沟通的问题之外,还有版本的问题,不同的版本需要的参数不一样。 ONC PRC的设计明显是面向函数的,而非面向对象。而当前面向对象的业务逻辑设计与实现方式已经成为主流。

    XML与SOAP

    XML是一种文本类的传输方式,格式没必要完全一样

    传输协议问题

    基于XML的最著名协议就是SOAP了,全称简单对象访问协议。它使用XML编写简单的请求和回复消息,并用HTTP协议进行传输。 SOAP将请求和回复放到一个信封里面,就像是传递一个邮件一样。信封里的信分抬头和正文。

    POST /purchaseOrder HTTP/1.1 Host: www.geektime.com 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.geektime.com/perchaseOrder"> <m:purchaseOrder"> <order> <date>2018-07-01</date> <className>趣谈网络协议</className> <Author>刘超</Author> <price>68</price> </order> </m:purchaseOrder> </soap:Body> </soap:Envelope>

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

    协议约定问题

    WSDL,Web服务描述语言,它是一个XML。 定一个类型order

    <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/geektime"> <xsd:complexType name="order"> <xsd:element name="date" type="xsd:string"></xsd:element> <xsd:element name="className" type="xsd:string"></xsd:element> <xsd:element name="Author" type="xsd:string"></xsd:element> <xsd:element name="price" type="xsd:int"></xsd:element> </xsd:complexType> </xsd:schema> </wsdl:types>

    定一个一个message 的结构

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

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

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

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

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

    最后,我们需要编写 service

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

    WSDL还是有些复杂的,不过好在有工具可以生成。 对于某个服务,哪怕是一个陌生人,都可以通过在服务地址后面加上?wsdl来获取这个文件。

    服务发现问题

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

    小结:

    原来的二进制RPC有很多的缺点,格式要求严格,修改过于复杂,不面向对象,于是产生了基于文本的调用方式-基于XML的SOAP。SOAP有三大要素:协议约定用WSDL,传输协议用HTTP,服务发现用UDDL。
    最新回复(0)