6 使用soap客户端_网络协议 20 - RPC 协议(上)- 基于XML的SOAP协议

上一节我们了解 RPC 的经典模型和设计要点,并用最早期的 ONC RPC 为例子,详述了具体的实现。而时代在进步,ONC RPC 逐渐因为各种问题被替代,SOAP 协议就是替代者之一。

ONC RPC 存在的问题

    ONC RPC 将客户端要发送的参数,以及服务端要发送的回复,都压缩为一个二进制串,这样固然能够解决双方的协议约定问题,但是存在一定的不方便。

    首先,需要双方的压缩格式完全一致,一点都不能差。一旦有少许的差错,多一位,少一位或者错一位,都可能造成无法解压缩。当然,我们可以用传输层的可靠性以及加入校验值等方式,来减少传输过程中的差错。

    其次,协议修改不灵活。如果不是传输过程中造成的差错,而是客户端因为业务逻辑的改变,添加或者删除了字段,或者服务端添加或者删除了字段,而双方没有及时通知,或者线上系统没有及时升级,就会造成解压缩不成功。

    因而,当业务发生改变,需要多传输一些参数或者少传输一些参数的时候,都需要及时通知对方,并且根据约定好的协议文件重新生成双方的 Stub 程序。自然,这样灵活性比较差。

    如果仅仅是沟通的问题也还好解决,其实更难弄的还有版本的问题。比如在服务端提供一个服务,参数的格式是版本一的,已经有 50 个客户端在线上调用了。现在有一个客户端有个需求,要加一个字段,怎么办呢?这可是一个大工程,所有的客户端都要适配这个,需要重新写程序,加上这个字段,但是传输值是 0,不需要这个字段的客户端很“冤”,本来没我啥事儿,为啥让我也忙活?

    最后,ONC RPC 的设计明显是面向函数的,而非面向对象。而当前面向对象的业务逻辑设计与实现方式已经成为主流。

    这一切的根源就在于压缩。这就像平时我们爱用缩略语。如果是篮球爱好者,你直接说 NBA,他马上就知道什么意思,但是如果你给一个大妈说 NBA,她可能就不知所云。

    所以,这种 RPC 框架只能用于客户端和服务端全由一拨人开发的场景,或者至少客户端和服务端的开发人员要密切沟通,相互合作,有大量的共同语言,才能按照既定的协议顺畅地进行工作。

XML 与 SOAP

    但是,一般情况下,我们做一个服务,都是要提供给陌生人用的,你和客户不会经常沟通,也没有什么共同语言。就像你给别人介绍 NBA,你要说美国职业篮球赛,这样不管他是干啥的,都能听得懂。

    放到我们的场景中,对应的就是用文本类的方式进行传输。无论哪个客户端获得这个文本,都能够知道它的意义。

    一种常见的文本类格式是 XML。我们这里举个例子来看。

<?xml version="1.0" encoding="UTF-8"?>
<cnblog:purchaseOrder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cnblog="http://www.example.com"><order><date>2019-01-08</date><className> 板栗焖鸡 </className><price>58</price></order>
</cnblog:purchaseOrder>

    我这里不准备详细讲述 XML 的语法规则,但是你相信我,看完下面的内容,即便你没有学过 XML,也能一看就懂,这段 XML 描述的是什么,不像全面的二进制,你看到的都是 010101,不知所云。

    有了这个,刚才我们说的那几个问题就都不是问题了。

    首先,格式没必要完全一致。比如如果我们把 price 和 author 换个位置,并不影响客户端和服务端解析这个文本,也根本不会误会,说这个作者的名字叫 68。

    如果有的客户端想增加一个字段,例如添加一个推荐人字段,只需要在上面的文件中加一行:

<recommended> Gary </recommended>

    对于不需要这个字段的客户端,只要不解析这一行就是了。只要用简单的处理,就不会出现错误。

    另外,这种表述方式显然是描述一个订单对象的,是一种面向对象的、更加接近用户场景的表示方式。

    既然 XML 这么好,接下来我们来看看怎么把它用在 RPC 中。

传输协议问题

    我们先解决第一个,传输协议的问题。

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

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

POST /purchaseOrder HTTP/1.1
Host: www.cnblog.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.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 正文给 http://www.geektime.com ,从而下一个单,这个订单封装在 SOAP 的信封里面,并且表明这是一笔交易(transaction),而且订单的详情都已经写明了。

协议约定问题

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

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

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

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

<wsdl:types><xsd:schema targetNamespace="http://www.example.org/cnblog"><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.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。

欢迎添加个人微信号:Like若所思。

欢迎关注我的公众号,不仅为你推荐最新的博文,还有更多惊喜和资源在等着你!一起学习共同进步!

edc853b0b23eb8927365d9dc0610e22e.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于HashMap容量的初始化,还有这么多学问

转载自 关于HashMap容量的初始化&#xff0c;还有这么多学问在《HashMap中傻傻分不清楚的那些概念》文章中&#xff0c;我们介绍了HashMap中和容量相关的几个概念&#xff0c;简单介绍了一下HashMap的扩容机制。文中我们提到&#xff0c;默认情况下HashMap的容量是16&#xff0…

Microservice Anti-patterns

在最近的一次Microservices Practitioner Summit中&#xff0c;原Netflix工程师介绍了一种越来越常见的对Microservice的误用。简单地说&#xff0c;大家在搭建一个基于Microservice的服务时常常依赖同一套类库&#xff0c;进而使得Microservice中的各个子服务无法选择最适合的…

css 图片换行_好程序员web前端学习路线分享CSS浮动-文档流篇

1、纯文本的排列。文档流就像我们的文本内容一样&#xff0c;所有的文字都会紧挨着&#xff0c;一个个排列下来&#xff0c;如果到了边界&#xff0c;就会换一行排列。当然如果敲回车或者按下空格键一般都会认为是一个词间距&#xff0c;因为英文中每个单词之间是有距离的&…

京东购物车的 Java 架构实现及原理

转载自 京东购物车的 Java 架构实现及原理 今天来写一下关于购物车的东西, 这里首先抛出四个问题: 1&#xff09;用户没登陆用户名和密码,添加商品, 关闭浏览器再打开后 不登录用户名和密码  问&#xff1a;购物车商品还在吗&#xff1f; 2&#xff09;用户登陆了用户名密…

程序员求职面试三部曲之三:快速适应新的工作环境

新进一家公司总有各种的不适应&#xff0c;或兴奋&#xff0c; 或紧张&#xff0c;或不安&#xff0c;或迷茫各种情绪兼而有之。曾经有个家伙好不容易进了A公司&#xff0c;本来是要替代另一位即将离职的小伙伴的&#xff0c;结果&#xff0c;走得比那位兄弟还快&#xff0c;只…

问的书写规则是什么意思_化学式的定义及其书写规则

化学式的定义及其书写规则化学式是用元素符号表示纯净物组成及原子个数的式子。分子晶体的化学式叫做分子式&#xff0c;可以表示这种物质的分子构成。下面是百分网小编给大家整理的化学式的简介&#xff0c;希望能帮到大家!化学式的定义用元素符号表示纯净物组成及原子个数的式…

微软企业应用开发三大方向:跨平台、开放/开源与DevOps

软件和互联网正在改变传统企业&#xff0c;软件的职能逐渐从管理内部员工变成核心的商业竞争能力&#xff0c;在今天这种大环境下&#xff0c;我们应该用的新开发技术和方法。微软公司全球资深副总裁、开发平台事业部潘正磊&#xff08;Julia&#xff09;认为&#xff0c;把IT托…

Java程序员最常犯的 10 个错误

转载自 Java程序员最常犯的 10 个错误 这个列表总结了Java开发人员经常犯的10个错误。一 、把数组转成ArrayList 为了将数组转换为ArrayList&#xff0c;开发者经常会这样做&#xff1a; List list Arrays.asList(arr); 使用Arrays.asList()方法可以得到一个ArrayList&…

mysql5.1升级5.5_mysql数据库迁移,由版本5.1升级至5.5.29,需要注意哪些

caching_sha2_password认证插件提供更多的密码加密方式&#xff0c;并62616964757a686964616fe59b9ee7ad9431333433636131且在加密方面具有更好的表现&#xff0c;目前MySQL 8.0选用caching_sha2_password作为默认的认证插件&#xff0c;MySQL 5.7的认证插件是MySQL_native_pas…

dotnetConf 2016 线上虚拟大会

为期三天&#xff08;6月7日-9日&#xff09;的Channel9 免费.NET线上虚拟大会&#xff0c;微软产品团队及.NET社区精英一起徜徉在.NET的世界&#xff01; 与大咖Scott Hunter, Miguel de Icaza (Xamarin CTO) , ScottHanselman及其他.NET大牛一起学习如何利用.NET开发跨…

mysql的on和in用法_数据库中in、on、with的用法及示例。

with用法&#xff1a;创建一个表&#xff1a;create table regr (pid integer,id integer, name char(20))alter table regr alter id set not null add primary key(id)insert into regr values(-1,1,library),(1,2,news),(2,3,world news),(2,4,politics),(2,5,bussiness)(2,…

文档数据库RavenDB-介绍与初体验

不知不觉&#xff0c;“.NET平台开源项目速览“系列文章已经15篇了&#xff0c;每一篇都非常受欢迎&#xff0c;可能技术水平不高&#xff0c;但足够入门了。虽然工作很忙&#xff0c;但还是会抽空把自己知道的&#xff0c;已经平时遇到的好的开源项目分享出来。今天就给大家介…

双机热备的原理

转载自 双机热备的原理夜半惊魂 上次的文章《负载均衡的原理》中讲到&#xff0c;张大胖在Bill的指导下&#xff0c;成功地开发了一个四层的负载均衡软件&#xff0c; 把流量“均匀地”分发到了后面的几个服务器中&#xff0c; 获得了老板的1000块钱奖励。但是张大胖心中隐隐不…

c# 向mysql插入数据_C#连接mysql数据库 及向表中插入数据的方法

mysql 语句操作&#xff1a;创建数据库&#xff1a;create database hotelATMDb;use hotelATMDb;C#连接mysql1、引用 dll MySql.Data.dll 下载地址&#xff1a;http://download.csdn.net/detail/chen504390172/67461312、引用 using MySql.Data.MySqlClient;连接语句&#xff1…

微软CEO纳德拉开讲,2016微软开发者峰会在京召开

6月1日&#xff0c;2016微软开发者峰会在京召开。 来自微软总部的高层、技术大拿&#xff0c; 以及来自微软亚洲研究院、微软亚太研发集团、Xamarin 总部团队、微软中国开发体验及平台合作事业部的技术专家对各平台的开发进行技术探讨&#xff0c;向开发者展示了一系列引人入胜…

Linux下如何避免误操作执行 rm

转载自 Linux下如何避免误操作执行 rm最近IT圈子流行着一个段子&#xff1a;某个蠢萌的程序员&#xff0c;不小心在公司的服务器上输入了 rm -rf/ 指令&#xff0c;结果......现在还没出狱呢。当然&#xff0c;绝大部分程序员不可能犯下如此低级的错误&#xff0c;更何况也没有…

Consul入门

简介 为什么要用consul&#xff0c;这里就不详细介绍了&#xff0c;本文重点是Consul的搭建和使用过程。 Consul搭建 参考文献&#xff1a;http://tonybai.com/2015/07/06/implement-distributed-services-registery-and-discovery-by-consul/ 下载consul和consul UI 官方地址&…

Java Socket编程----通信是这样炼成的

转载自 Java Socket编程----通信是这样炼成的 Java最初是作为网络编程语言出现的&#xff0c;其对网络提供了高度的支持&#xff0c;使得客户端和服务器的沟通变成了现实&#xff0c;而在网络编程中&#xff0c;使用最多的就是Socket。像大家熟悉的QQ、MSN都使用了Socket相关的…

mysql级联复制转换成一主两从_一主两从转级联复制

一主两从 转 级联复制 示意图如下M ---> S1\ > M ---> S1 ---> S2\ --> S2如果有开启GTID操作起来方便多&#xff0c;GTID是唯一的&#xff0c;直接操作即可。如果使用file_name、position可以使用如下办法(现在还没开启gtid真的是无力吐槽)# 步骤1、# 现将S2的…

细说ASP.NET Core与OWIN的关系

前言 最近这段时间除了工作&#xff0c;所有的时间都是在移植我以前实现的一个Owin框架&#xff0c;相当移植到到Core的话肯定会有很多坑&#xff0c;这个大家都懂&#xff0c;以后几篇文章可能会围绕这个说下&#xff0c;暂时就叫《Dotnet Core踩坑记》吧&#xff0c;呵呵。 接…