RPC 简介
RPC -- Remote Procedure Call,即远程过程调用。
RPC(Remote Procedure Call Protocol)—— 远程过程调用协议。
它是一个计算机通信协议,该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,例:Java RMI。
远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。
为了允许不同的客户端均能访问服务器,许多标准化的 RPC 系统应运而生了。其中大部分采用接口描述语言(Interface Description Language,IDL),方便跨平台的远程过程调用。
RPC 工作原理
运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:
1、调用客户端句柄,执行传送参数
2、调用本地系统内核发送网络消息
3、消息传送到远程主机
4、服务器句柄得到消息并取得参数
5、执行远程过程
6、执行的过程将结果返回服务器句柄
7、服务器句柄返回结果,调用远程系统内核
8、消息传回本地主机
9、客户句柄由内核接收消息
10、客户接收句柄返回的数据
RPC OVER HTTP
Microsoft RPC-over-HTTP 部署(RPC over HTTP)允许 RPC 客户端安全和有效地通过 Internet 连接到 RPC 服务器程序并执行远程过程调用。这是在一个名称为 RPC-over-HTTP 代理,或简称为 RPC 代理的中间件的帮助下完成的。
RPC 代理运行在 IIS 计算机上。它接受来自 Internet 的 RPC 请求,在这些请求上执行认证,检验和访问检查,如果请求通过所有的测试,RPC 代理将请求转发给执行真正处理的 RPC 服务器。通过RPC over HTTP,RPC客户端不和服务器直接通信,它们使用 RPC 代理作为中间件。
RPC 协议结构
远程过程调用(RPC)信息协议由两个不同结构组成:调用信息和答复信息。
信息流程如下所示:
- RPC:远程过程调用流程
- RPC 调用信息:每条远程过程调用信息包括以下无符号整数字段,以独立识别远程过程:
程序号(Program number)
程序版本号(Program version number)
过程号(Procedure number)
RPC 调用信息主体形式如下:
- struct call_body
unsigned int rpcvers;
unsigned int prog;
unsigned int vers;
unsigned int proc;
opaque_auth cred;
opaque_auth verf;
- parameter
- parameter
RPC 答复信息:
RPC 协议的答复信息的改变取决于网络服务器对调用信息是接收还是拒绝。
答复信息请求包括区别以下情形的各种信息:
- RPC 成功执行调用信息。
- RPC 的远程实现不是协议第二版,返回 RPC 支持的最低和最高版本号。
- 在远程系统中,远程程序不可用。
- 远程程序不支持被请求的版本号,返回远程程序所支持的最低和最高版本号。
- 请求的过程号不存在。通常是呼叫方协议或程序差错。
RPC 答复信息形式如下:
enum reply_stat stat
{
MSG_ACCEPTED=0,
MSG_DENIED=1
}。
JSON-RPC
JSON-RPC 是一种以 json 为协议的远程调用服务,具有开发调试简单,多平台通用的特性。
JSON-RPC 是一种以 json 为消息格式的远程调用服务,它是一套允许运行在不同操作系统、不同环境的程序实现基于 Internet 过程调用的规范和一系列的实现。这种远程过程调用可以使用 http 作为传输协议,也可以使用其它传输协议,传输的内容是 json 消息体。
JSON-RPC 和 XML-RPC 相比具有很多优点。首先 XML-RPC 是以 xml 作为消息格式,xml 具有体积大,格式复杂,传输占用带宽。程序对 xml 的解析也比较复杂,并且耗费较多服务器资源。json 相比 xml 体积小巧,并且解析相对容易很多。
JSON-RPC 使用
1、请求
JSON-RPC 非常简单,在请求时向服务器传输数据格式如下(基于JSON2.0):
{
"jsonrpc" : 2.0,
"method" : "sayHello",
"params" : ["Hello JSON-RPC"],
"id" : 1
}
-
jsonrpc
:定义 JSON-RPC 版本。 -
method
:调用的方法名。 -
params
:方法传入的参数,若无参数则为null
。 -
id
:调用标识符。可以为字符串,不推荐包含小数(不能准确二进制化),或为null
(可能引起混乱)。
2、响应
服务器返回的数据格式也为 JSON,其格式如下:
{
"jsonrpc" : 2.0,
"result" : "Hell JSON-RPC",
"error" : null,
"id" : 1
}
-
jsonrpc
:定义 JSON-RPC 版本。 -
result
:方法返回值,调用成功时,不能为null
,调用错误时,必须为null
。 -
error
:调用时错误,无错误返回null
,有错误时则返回一个错误对象。 -
id
:调用标识符,与调用方传入的标识一致,当请求中的id
检查发生错误时(转换错误/无效请求),则必须返回null
。
3、错误
(1)错误对象:
{
"code" : 1,
"message" : "Nothing found",
"data":null
}
-
code
:一个表示错误类型的数字。 -
message
:错误描述。 -
data
:附加信息,可为null
。
(2)错误码:
错误码 -32768 到 -32000 作为预定义错误的保留值,该范围内的任何未定义代码为未来保留使用。
代码 | 错误 | 含义 |
---|---|---|
-32700 | 解析错误 | 服务器接收到无效的JSON;服务器解析JSON文本发生错误。 |
-32600 | 无效的请求 | 发送的JSON不是一个有效的请求。 |
-32601 | 方法未找到 | 方法不存在或不可见。 |
-36602 | 无效的参数 | 无效的方法参数。 |
-36603 | 内部错误 | JSON-RPC内部错误。 |
-32000 ~ -32099 | 服务器端错误 | 保留给具体实现服务器端错误。 |
4、批量调用
客户端可以发送一个请求对象数组来进行批量调用。当所有的请求都响应完毕后,服务器应以一个数组作为响应,每个请求都应该对应一个请求对象。服务器可以以任何宽度的并行性,以任意的顺序,并发的批量处理一个 RPC 调用。客户端可以通过 id
将请求和响应进行匹配。
5、示例
(1)列表形式参数:
- 请求
{
"jsonrpc":"2.0",
"method": "subtract",
"params":[42, 23],
"id": 1
}
- 响应
{
"jsonrpc":"2.0",
"result": 19,
"id": 1
}
(2)key-value 形式参数:
- 请求
{
"jsonrpc":"2.0",
"method": "subtract",
"params":{
"subtrahend": 23,
"minuend": 42
},
"id": 3
}
- 响应
{
"jsonrpc":"2.0",
"result": 19,
"id": 3
}
(3)错误的调用(无 id
错误):
- 请求
{
"jsonrpc":"2.0",
"method": 1,
"params": "bar"
}
- 响应
{
"jsonrpc": "2.0",
"error":{
"code": -32600,
"message": "Invalid Request"
},
"id": null
}
API reference (JSON-RPC)
- https://en.bitcoin.it/wiki/API_reference_(JSON-RPC)
总结
欢迎留言讨论,有错误请指出,谢谢!
【联系我(QQ:3500229193)或者加入社群,请戳这里!】
参考链接
- https://en.wikipedia.org/wiki/Remote_procedure_call
- http://www.baike.com/wiki/RPC
- http://www.jsonrpc.org
- http://wiki.geekdream.com/Specification/json-rpc_2.0.html
- https://www.cnblogs.com/cielosun/p/6762550.html
更新日志
- 2018.06.14 第一次更新
- 2018.08.31 第二次更新