json-rpc 1.0规范解读

JSON可能是这个地球上最简单的文本数据格式了,可读、灵活、数据量小,编解码方便、速度快,对Unicode和特殊字符支持的好。对比下XML,就知道额外的各种标签节点需要浪费多少字节数。JSON字符默认都要使用Unicode形式,所有非ACSII字符都可以用\uXXXX表示,而不需要额外的转义。相比之下,XML里需要使用转义或是CDATA(类似HTML里的PRE标签)、或是Base64才能表示特殊数据。当然缺点也很明显,比二进制数据结构的数据量大,编解码慢,没有完备的类型系统,表达能力有限。

JSON-RPC是一个使用json对象作为数据载体的远程过程调用(Remote Process Call,RPC)技术。

"Does distributed computing have to be any harder than this? I don‘t think so." -- Jan-Klaas Kollhof

JSON-RPC的设计目标就是两个字:简单。我们知道一个rpc框架是为了2个系统间的交互通信,这就需要定义一个中间的数据传输格式。为了跟系统本身用的平台数据结构转换,需要提供一套序列化和反序列化这个数据格式的功能。然后就是需要某种通信协议来传输实际远程调用的数据。最后还需要通信的两端有实现的代码桩(stub&skeleton),这一般是基于动态代理或AOP实现的代理,一个可供调用的接口结构,使得框架隐藏了其他所有的技术细节(数据格式、序列化、网络传输等),程序里能像本地方法调用一样调用远程的方法。总结一下:

  1. 数据格式
  2. 序列化功能
  3. 通信协议
  4. 代码桩

JSON-RPC规范里只显式规定了数据格式(即JSON),建议了通信协议(TCP或是HTTP),序列化和代码桩没有提及。当然序列化比较好办,各种语言里都有丰富的JSON序列化库(参见参考资料1)。那么代码桩就完全留给了实现JSON-RPC规范的框架自己去处理了,通信协议这一块的具体处理也大部分需要框架自己考虑。

我们知道两个系统的通信,可能是同步阻塞的(每个请求要等响应完成以后再发下一个请求),也可能是异步非阻塞的(请求1发完,继续发请求2,哪个响应回来就处理哪个响应);也可能是单向的(one-way,发了就不管了、不要响应信息),也可能是请求-响应的(request-response),每个请求都需要有显式的回复。

JSON-RPC1.0里,把通信的双方当做对等的两个端。

  • 定义了如何发请求和返回结果、出错信息,
  • 如何处理单向和请求-响应的交互过程,
  • 以及双向异步请求如何匹配结果和请求,
  • 最后还添加了一个简单的类型提示(class hinting)扩展功能(想法很好,但是就两句话没细节,挺鸡肋的)。

我们来具体看看规范的内容。

请求(request)

请求端发送一个JSON对象表示自己要调用的方法,示例如下:

{ "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}

其中包含三个关键元素:

  • method:表示要调用的方法
  • params:表示参数的数组
  • id:表示这次请求是需要响应的,服务方需要提供一个同样是id为1的响应信息。

这个id字段非常有意思,一般的同步RPC都不需要考虑这个东西,因为一般情况下,一个RPC请求只包含一个请求,并且请求会等待响应信息返回,在这之前一直会阻塞调用方的处理线程,这样整个RPC才像是调用的本地方法。

响应(response)

一个典型的响应信息如下:

{ "result": "Hello JSON-RPC", "error": null, "id": 1}

关键元素也是3个:

  • result:表示返回结果,如果出错result必须为null
  • error:表示出错,如果请求成功,则error必须为null
  • id:表示为此响应对应的请求id

通知(notification)

通知信息类似一个请求,但是id必须为null。通知代表单向的请求,不能回复,可以由请求方发送给服务方,也可以由服务方发送给请求方(协议原则上要求双方对等,都可以是请求方或服务方,这一点上HTTP其实是不满足的)。

通信(transport)

  • TCP

协议推荐通信双方在TCP下使用字节流(byte stream)的方式交互。此时双方是对等的。关闭连接前必须给所有未应答的请求方发送一个错误信息。无效的请求或响应将会导致连接关闭。

  • HTTP

在一些限制的条件下,也可以使用HTTP作为通信协议。此时通信双方明显不在对等,有了客户端和服务器端。

考虑到HTTP的开销问题,协议允许一次POST可以带上多个rpc请求或通知。由于HTTP下,server不能够主动访问client,所以server可以在HTTP响应中附带上自己的请求和通知。这个地方协议们没有说清楚具体操作,细节也是个蛋疼的事儿。

类型提示(class
hinting)

非常简单,就是加了个属性表示构造函数constructor,可以用参数[param1,...]来初始化对象。而且如果对象初始化的时候调用了这个构造器,那么相应的属性(比如prop1)也会添加到对象,示例代码:

{"__jsonclass__":["constructor", [param1,...]], "prop1": ...}

协议没有具体说清楚这个地方,具体怎么操作,怎么对应原生环境里的类型,蛋疼++。

一个多次通信的例子

JSON-RPC过程如下,其中-->代表发送数据到服务方,<--代表服务方的响应:

--> {"method": "postMessage", "params": ["Hello all!"], "id": 99}
<-- {"result": 1, "error": null, "id": 99}
<-- {"method": "handleMessage", "params": ["user1", "we were just talking"], "id": null}
<-- {"method": "handleMessage", "params": ["user3", "sorry, gotta go now, ttyl"], "id": null}
--> {"method": "postMessage", "params": ["I have a question:"], "id": 101}
<-- {"method": "userLeft", "params": ["user3"], "id": null}
<-- {"result": 1, "error": null, "id": 101}

关于JSON-RPC1.0规范的进一步讨论

  • 关于通知

通知机制也可以用于类似FTP协议的NOOP,或是其他通讯协议里的Keep Alive心跳机制。在具体使用的过程中,定时的发送通知来确认双方都在线,并且可以捎带异步处理的信息。

  • 关于id

请求中id字段的作用,就跟JMS协议里的correlationID一样,可以起到区分多个请求的作用,这样又两个好处:

  1. 多个请求可以打包成一个请求,返回也可以返回多个响应,处理方按照id区分多个数据即可;
  2. 可以做异步的响应,反正我不保证顺序了,也能根据id来匹配原来是哪个请求来着。

特别是配合HTTP和通知功能,使得异步调用变得可能:客户端直接发送请求1后返回,继续发送请求2,请求3...等等;服务端在处理完成请求1后,可能把响应放到请求2或3的HTTP response报文返回,或者在接下里的某次交互里返回即可。

  • 关于类型

JSON-RPC跟XML-RPC非常类型,但是借助于XML本身的schema结构,XML-RPC定义了一套基础的数据类型、以及在基础上的构造复杂数据类型的能力,这样XML-RPC中就可以用于更复杂的业务交互场景。而JSON-RPC使用JS原生的弱类型,只能表示非常简单和模糊的元数据结构,不利于复杂场景和实现代码桩的生成工具。如果有一些更有效的schema约束,则可以把JSON-RPC应用得更广泛。

JSON-RPC的历史参见:whynamed-rpc-jsonrpc

参考资料

时间: 2024-10-10 22:47:04

json-rpc 1.0规范解读的相关文章

json-rpc 2.0规范解读

JSON-RPC2.0规范由JSON-RPC工作组([email protected])维护,发布于2010-03-26(基于2009-05-24的版本), 最近的更新于2013-01-04. 整体来说,2.0版本的JSON-RPC规范改动的很小,大的改动大概有3点: 参数可以用数组或命名参数 批量请求的细节明确化了 错误处理的机制标准化了 与1.0版本的兼容性 建议2.0规范的实现兼容1.0协议,但是不强制要求,如果不能兼容,建议给出友好提示. 请求和响应报文加了个参数表示协议的版本号:jso

JSON-RPC 2.0规范 翻译 中文版

JSON-RPC 2.0规范 起源日期: 2010-03-26(基于2009-05-24的版本) 修正: 2013-01-04 作者: JSON-RPC 工作组 <[email protected]> 1 概述 JSON-RPC是一个无状态的.轻量级的远程过程调用(RPC)协议.本规范主要围绕它的处理方式定义了几个数据结构和规则.这个概念可用于在同一进程中.套接字或HTTP之间.或其他很多消息传递的环境中传输数据.它使用JSON (RFC 4627)作为数据格式. JSON-RPC的设计很简单

测试JSON RPC远程调用(JSON客户端)

#include <string> #include <iostream> #include <curl/curl.h> /* 标题:JSon客户端 Author: Kagula LastUpdateDate:2014-05-17 描述:测试JSON RPC远程调用 测试环境:Windows 8.1.Visual Studio 2013 SP1 curl-7.36.0 CPPCMS 1.0.4(JSON服务端) Java Servlet (JSON服务端) */ sta

測试JSON RPC远程调用(JSONclient)

#include <string> #include <iostream> #include <curl/curl.h> /* 标题:JSonclient Author: Kagula LastUpdateDate:2014-05-17 描写叙述:測试JSON RPC远程调用 測试环境:Windows 8.1.Visual Studio 2013 SP1 curl-7.36.0 CPPCMS 1.0.4(JSON服务端) Java Servlet (JSON服务端) *

基于php的json rpc原理及应用

json rpc 是一种以json为消息格式的远程调用服务,它是一套允许运行在不同操作系统.不同环境的程序实现基于Internet过程调用的规范和一系列的实现.这种远程过程调用可以使用http作为传输协议,也可以使用其它传输协议,传输的内容是json消息体. 下面我们code一套基于php的rpc框架,此框架中包含rpc的服务端server,和应用端client: (一)PHP服务端RPCserver jsonRPCServer.php class jsonRPCServer { /** *处理

BPMN 2.0规范

.1. BPMN 2.0是什么呢? 业务流程模型注解(Business Process Modeling Notation - BPMN)是 业务流程模型的一种标准图形注解.这个标准 是由对象管理组(Object Management Group - OMG)维护的. 基本上,BPMN规范定义了任务看起来怎样的,哪些结构可以 与其他进行连接,等等.这就意味着 意思不会被误解. 标准的早期版本(1.2版以及之前)仅仅限制在模型上, 目标是在所有的利益相关者之间形成通用的理解, 在文档,讨论和实现业

JSON API 1.0 核心开发者自述 | 你所不知道的那些技术细节

2013年5月,Yehuda Katz 完成了JSON API(英文,中文) 技术规范的初稿.事情就发生在 RailsConf 之后,在那次会议上他和 Steve Klabnik 就 JSON 雏形的技术细节相聊甚欢.在沟通单一 Rails 服务器库-- ActiveModel::Serializers 和单一 JavaScript 客户端库-- Ember Data 的强烈呼声下,JSON API 应运而生(关于这段历史,我在2013年2月第一届 EmberCamp 上有一个演讲,感兴趣的可以

无法解决“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”与“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”之间的冲突。正在随意选择“Newtonsoft.Jso

今天的程序莫名报错:  无法解决“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”与“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”之间的冲突.正在随意选择“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, P

SD3.0协议解读一

前言: 老衲我近期研究的是SD/MMC卡驱动,研究过的SD/MMC驱动的贫僧们都应该知道SD/MMC协议是必不可少的一部分,除非你不想研究透SD/MMC驱动,那你大可只研究driver/mmc/host目录下的文件即可.说到SD/MMC协议,网上一搜,SD3.0的协议只有英文版的资料,要想真正理解协议,英文水平差的贫僧就可吃力了,老衲英文水平实在是一般,但是网上对SD3.0协议的解读相关的中文资料实在是少的可怜.老衲怒想写写对SD3.0协议的理解,于是这一系列的SD3.0协议解读将会陆续问世..