趣谈网络协议---基于XML的SOAP协议:不要说NBA,请说美国职业篮球联赛

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u012319493/article/details/82931074

ONC RPC 存在哪些问题?

ONC RPC 将客户端要发送的参数,及服务要发送的回复,都压缩为一个二进制串,存在不便。

  • 双方的压缩格式完全一致,一点都不能差,有一位不同都可能造成无法解压缩。
  • 协议修改不灵活,业务发生改变时,修改了传递的参数,如果没有及时通知对方,重新生成双方的 Stub 程序,就会造成解压缩不成功。
  • 版本问题。服务端提供的服务的参数格式为版本1,如果有一个客户端需要加一个字段,其余上线的客户端都要适配。
  • ONC RPC 的设计不是面向对象的。

XML 与 SOAP

SOAP 采用文本格式 XML 进行传输。

  • 格式不需要完全一致。比如不同字段可互换位置。
  • 可灵活修改字段。比如有的客户端想增加一个字段,不需要该字段的客户端不解析便可。
  • 面向对象,是更加接近用户场景的表达方式。

如何将 XML 用在 RPC 中?

1、传输协议问题

基于 XML 最著名的通信协议是 SOAP(Simple Object Access Protocol,简单对象访问协议),使用 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 方法,给 www.geektime.com 发送一个格式为 application/soap + xml 的 XML 正文,从而下一个单,该订单封装在 SOAP 信封中,并表明这是一笔交易(transaction),订单详情已写明。

2、协议约定问题

双方的协议约定是什么样的?如何对服务进行描述,方便客户端调用?需要一种相对比较严谨的 Web 服务描述语言,WSDL(Web Service Discription Languages),也是一个 XML 文件。

  • 定义一个类型 order,与上面的 XML 对应起来。
 <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 生成客户端 Stub。

3、服务发现问题

UDDI(Universal Description, Discovery and Integration),统一描述、发现和继承协议,是一个注册中心,服务提供方可将 WSDL 文件发布到该注册中心,客户端可查找到服务的描述,封装为本地的客户端进行调用。

猜你喜欢

转载自blog.csdn.net/u012319493/article/details/82931074