当前位置: 首页 > news >正文

JSON-RPC 2.0 规范

1. 概述

JSON-RPC 是一种无状态、轻量级的远程过程调用(RPC)协议。本规范主要定义了几种数据结构以及它们的处理规则。它与传输协议无关,能够在同一进程内、通过套接字、HTTP 或多种消息传递环境中使用。它使用 JSON(RFC 4627)作为数据格式。

设计上,它的目标是简洁明了。

2. 术语

文中使用的关键词如 “MUST”、“MUST NOT”、“REQUIRED”、“SHALL”、“SHALL NOT”、“SHOULD”、“SHOULD NOT”、“RECOMMENDED”、“MAY” 和 “OPTIONAL” 的解释遵循 RFC 2119。

JSON-RPC 使用 JSON 作为数据格式,JSON 的类型系统包括四种原始类型(字符串、数字、布尔值和 null)以及两种结构化类型(对象和数组)。此文中提到的 JSON 类型首字母总是大写。

所有 Client 和 Server 之间交换的成员名称,特别是涉及匹配的,应该区分大小写。方法(method)和函数(function)、过程(procedure)可以视为同义词。

  • Client:请求对象的发起者和响应对象的处理者。
  • Server:响应对象的发起者和请求对象的处理者。

一个实现可以同时担任这两个角色,分别处理不同客户端或同一客户端的请求。

3. 兼容性

JSON-RPC 2.0 的请求对象和响应对象与现有的 JSON-RPC 1.0 客户端或服务器不兼容。2.0 版本始终包含名为 “jsonrpc” 的字段,值为 “2.0”;而 1.0 版本没有这个字段。大多数 2.0 实现应该尝试处理 1.0 对象,尽管不支持点对点或类提示的特性。

4. 请求对象

RPC 调用通过发送一个请求对象给服务器表示。请求对象包含以下成员:

  • jsonrpc:指定 JSON-RPC 协议的版本。值必须为 “2.0”。
  • method:包含要调用的方法名称。方法名称以 “rpc” 开头的为系统保留,不能使用。
  • params:一个结构化的值,包含在方法调用时使用的参数。该字段可以省略。
  • id:由客户端指定的标识符,必须是字符串、数字或 null。如果省略该字段,则默认为通知类型。若包含,服务器返回的响应对象也必须包含该值,以便关联上下文。

4.1 通知

通知是没有 “id” 字段的请求对象。通知意味着客户端不关心响应,因此服务器不需要返回响应。通知不能确认,因此客户端无法得知是否发生错误。

4.2 参数结构

参数可以通过位置或名称传递:

  • 按位置传递:参数必须是一个数组,按照服务器预期的顺序传递。
  • 按名称传递:参数必须是一个对象,其中成员名称应与服务器预期的参数名称完全匹配。

5. 响应对象

服务器在处理请求时会返回一个响应对象,除非是通知类型。响应对象包含以下成员:

  • jsonrpc:指定 JSON-RPC 协议的版本。值必须为 “2.0”。
  • result:在成功时返回,表示方法的返回值。出错时,该字段不能存在。
  • error:在错误时返回,表示方法执行中的错误。没有错误时,该字段不能存在。包含错误详情的对象。
  • id:与请求对象中的 id 值相同。如果请求对象的 id 无法识别,返回 null。

5.1 错误对象

当 RPC 调用遇到错误时,响应对象中的 error 字段会包含以下信息:

  • code:一个整数,表示错误类型。
  • message:简短的错误描述。
  • data:一个可选的字段,包含错误的详细信息,值由服务器定义。

保留错误代码范围为 -32768 到 -32000,具体的错误代码定义如下:

错误代码错误信息含义
-32700解析错误无效的 JSON 格式。服务器解析 JSON 时出错。
-32600无效的请求发送的 JSON 不是有效的请求对象。
-32601方法未找到方法不存在或不可用。
-32602参数无效方法参数无效。
-32603内部错误服务器内部错误。
-32000 到 -32099服务器错误预留的服务器实现错误。

6. 批量请求

客户端可以同时发送多个请求对象,服务器将处理并返回相应的响应对象。批量请求的响应是一个数组,包含每个请求的响应对象。

  • 响应中的每个对象对应一个请求对象,通知类型的请求不会返回响应对象。
  • 批量请求可以并行处理,服务器处理顺序和并行度可以自由选择。
  • 如果批量请求本身无效,服务器返回一个单一的响应对象,而不是空数组。

7 示例

  1. 带位置参数的 RPC 调用

    --> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 1}--> {"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 2}
    <-- {"jsonrpc": "2.0", "result": -19, "id": 2}
    
  2. 带命名参数的 RPC 调用

    --> {"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 3}--> {"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}
    <-- {"jsonrpc": "2.0", "result": 19, "id": 4}
    
  3. 通知

    --> {"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}
    --> {"jsonrpc": "2.0", "method": "foobar"}
    
  4. 调用不存在的方法

    --> {"jsonrpc": "2.0", "method": "foobar", "id": "1"}
    <-- {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}
    
  5. 无效的 JSON 调用

    --> {"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]
    <-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
    
  6. 无效请求对象的调用

    --> {"jsonrpc": "2.0", "method": 1, "params": "bar"}
    <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    
  7. 批量请求,含无效的 JSON

    --> [{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method": "foobar"}
    ]
    <-- {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
    
  8. 带空数组的请求

    --> []
    <-- {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    
  9. 带无效元素的批量请求

    --> [1]
    <-- [{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    ]
    
  10. 无效的批量请求

    --> [1,2,3]
    <-- [{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
    ]
    
  11. 批量请求

    --> [{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},{"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", "result": 19, "id": "2"},{"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"}
    ]
    
  12. 批量请求(全是通知)

    --> [{"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
    ]
    <-- // 所有通知批量没有返回内容
    

8 扩展

以 rpc. 开头的方法名称是为系统扩展保留的,必须避免用于其他目的。每个系统扩展在相关规范中定义。所有系统扩展都是可选的。

http://www.dtcms.com/a/304494.html

相关文章:

  • 寻找重复元素-类链表/快慢指针
  • 【lucene】currentFrame与staticFrame
  • Springboot+vue智能家居商城的设计与实现
  • 数据赋能(341)——技术平台——模块化
  • 2024高考综合本科率对比
  • 本地安装 SQLite 的详细步骤
  • Qt模型/视图结构
  • Python入门第三课:进阶编程技能: 文件操作与数据持久化
  • 【C++算法】78.BFS解决FloodFill算法_算法简介
  • 量子计算革命:重新定义计算的边界与未来
  • react 的 useTransition 、useDeferredValue
  • ZKmall开源商城架构工具链:Docker、k8s 部署与管理技巧
  • 反射核心:invoke与setAccessible方法详解
  • SpringBoot整合RocketMQ(阿里云ONS)
  • 数据库4.0
  • Linux 文件管理高级操作:复制、移动与查找的深度探索
  • Deep Research(信息检索增强)认识和项目实战
  • 计算器4.0:新增页签功能梳理页面,通过IO流实现在用户本地存储数据
  • 点控云数据洞察智能体:让房地产决策有据可循,让业务增长稳健前行
  • 【LLM】——qwen2.5 VL模型导出到onnx
  • Python中二进制文件操作
  • 快速了解逻辑回归
  • 【华为机试】43. 字符串相乘
  • 【LeetCode 随笔】
  • 【深度学习】独热编码(One-Hot Encoding)
  • 开源 Arkts 鸿蒙应用 开发(十一)证书和包名修改
  • C语言在键盘上输入一个3行3列矩阵的各个元素的值(值为整数),然后输出主对角线元素的积,并在fun()函数中输出。
  • 信号上升时间与带宽的关系
  • Leetcode-3361两个字符串的切换距离
  • FastAPI入门:请求体的字段、嵌套模型、额外数据、额外数据类型