StreamJsonRpc 是一个实现了 JSON-RPC 通信协议的开源 .NET 库, 在介绍 StreamJsonRpc 之前, 我们先来了解一下 JSON-RPC.
JSON-RPC 介绍
JSON-RPC 是一个无状态且轻量级的远程过程调用 (RPC) 协议, 其使用 JSON(RFC 4627)作为数据格式.
目前 JSON-RPC 的版本已发展到 2.0,JSON-RPC 2.0 与 1.0 的约定规范是不一样的. 2.0 包含一个名为 jsonrpc 且值为 2.0 的成员, 而 1.0 版本是不包含的. 所以我们可以很容易在两个版本间区分出 2.0.
JSON-RPC 在客户端与服务端之间交换的所有成员名应是区分大小写的, 函数, 方法, 过程都认为是可互换的. 客户端被定义为请求对象的来源及响应对象的处理程序; 服务端被定义为响应对象的起源和请求对象的处理程序.
请求对象
发送一个请求对象至服务端代表一个 RPC 调用, JSON-RPC 2.0 规定一个请求对象包含下列成员:
jsonrpc: 指定 JSON-RPC 协议版本的字符串, 必须准确写为 "2.0".
method: 包含所要调用方法名称的字符串, 以 rpc 开头的方法名, 用英文句号连接的为预留给 rpc 内部的方法名及扩展名, 且不能在其他地方使用.
params: 调用方法所需要的结构化参数值, 该成员参数可以被省略.
id: 已建立客户端的唯一标识, 值必须包含一个字符串, 数值或 NULL 空值. 如果不包含该成员则被认定为是一个通知. 该值一般不为 NULL, 若为数值则不应该包含小数.
没有包含 id 成员的请求对象为通知, 作为通知的请求对象表明客户端对服务端响应不感兴趣, 服务端可以不响应请求对象给客户端.
下面是几个请求对象的 JSON 结构示例("-->" 表示发送,"<--" 表示响应, 下同):
- --> {
- "jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1
- }
- --> {
- "jsonrpc": "2.0", "method": "subtract", "params": {
- "minuend": 42, "subtrahend": 23
- }, "id": 4
- }
- --> {
- "jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]
- } // 通知
响应对象
当客户端发起一个 RPC 调用时, 除通知之外, 服务端都必须回复响应. 响应也表示为一个 JSON 对象, 使用以下成员:
jsonrpc: 指定 JSON-RPC 协议版本的字符串, 必须准确写为 "2.0".
result: 调用成功时响应给客户端的结果, 当调用发生错误时可以不包含该成员.
error: 调用发生错误时返回给客户端的错误信息, 在调用失败时必须包含该成员.
id: 对应请求对象的 "id", 其值必须与请求对象中的 "id" 值一致.
响应对象必须包含 result 或 error 成员之一.
响应对象的 error 成员的结构包含下列成员:
code: 使用数值表示该异常的错误类型, 必须为整数.,
message: 对该错误的简单描述字符串, 该描述应尽量限定在简短的一句话.
data: 包含关于错误的附加信息, 可忽略.
其中 -32768 至 -32000 为保留的预定义错误代码, 各保留错误代码的含义请查看文末参考链接[1].
下面是几个响应对象的 JSON 结构示例:
- <-- {
- "jsonrpc": "2.0", "result": 19, "id": 1
- }
- <-- {
- "jsonrpc": "2.0", "error": {
- "code": -32601, "message": "Method not found"
- }, "id": "1"
- }
- <-- {
- "jsonrpc": "2.0", "error": {
- "code": -32700, "message": "Parse error"
- }, "id": null
- } // 无效调用
批量调用
当需要同时发送多个请求对象时, 客户端可以发送一个包含所有请求对象的数组.
当批量调用的所有请求对象处理完成时, 服务端则需要返回一个包含相对应的响应对象数组. 每个响应对象都应对应每个请求对象, 除非是通知的请求对象. 服务端可以并发的, 可以以任意顺序和任意宽度并行处理这些批量调用. 而客户端应该是基于各个响应对象中的 id 成员来匹配对应的请求对象.
若批量调用没有需要返回的响应对象, 则服务端不需要返回任何结果.
下面是一个批量请求及响应的 JSON 结构示例:
- --> [
- {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
- {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
- {"foo": "boo"},
- {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
- {"jsonrpc": "2.0", "method": "get_data", "id": "9"}
- ]
- <-- [
- {"jsonrpc": "2.0", "result": 7, "id": "1"},
- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},
- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},
- {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"}
- ]
当批量请求对象都是通知时, 服务端不需要返回结果.
StreamJsonRpc 库介绍
StreamJsonRpc 是一个实现了 JSON-RPC 通信协议的 .NET 库, 支持 .NET Core. 它把 RPC 的调用封装为公开的 .NET API, 可以很方便的进行 RPC 请求的发送和接收操作. StreamJsonRpc 是微软官方的一个开源库, 目前 Star 数接近 300, 貌似知道的人不多或者用的人不多. GitHub 地址:
https://github.com/microsoft/vs-streamjsonrpc
StreamJsonRpc 可以在 Stream,webSocket 或 System.IO.Pipelines 管道上工作, 独立于底层传输. 除了包含 JSON-RPC 规范所需的特性外, 它额外还有如下优点:
请求取消
.NET 事件作为通知
动态客户端代理生成
支持紧凑的 MessagePack 二进制序列化
易于实现插件式架构的消息处理和格式化
使用 StreamJsonRpc 主要有四个基本步骤: 建立 JSON-RPC 连接, 发送 RPC 请求, 接收 RPC 请求, 断开连接.
这一篇主要介绍一些预备知识, 下一篇将通过示例演示并详细介绍 StreamJsonRpc 的使用, 敬请期待!
参考:
[1]. https://www.jsonrpc.org/specification
[2]. https://github.com/microsoft/vs-streamjsonrpc
来源: https://www.cnblogs.com/willick/p/13233704.html