firemail
标题:
JSON-RPC是什么
[打印本页]
作者:
Qter
时间:
2024-10-31 19:50
标题:
JSON-RPC是什么
JSON-RPC 是一个基于 JSON 的轻量级远程过程调用(RPC)协议。让我详细解释它的核心概念和使用方式:
1. 基本格式:
```javascript
// 请求格式
{
"jsonrpc": "2.0", // 协议版本,固定为 "2.0"
"method": "subtract", // 要调用的方法名
"params": [42, 23], // 参数,可以是数组或对象
"id": 1 // 请求标识符,用于匹配响应
}
// 响应格式(成功)
{
"jsonrpc": "2.0",
"result": 19, // 结果
"id": 1 // 对应请求的id
}
// 响应格式(错误)
{
"jsonrpc": "2.0",
"error": {
"code": -32600, // 错误码
"message": "Invalid Request" // 错误信息
},
"id": 1
}
```
2. 通知(Notification):
```javascript
// 通知是不需要响应的请求,没有 id 字段
{
"jsonrpc": "2.0",
"method": "update",
"params": [1, 2, 3, 4, 5]
}
```
3. 批量请求:
```javascript
// 多个请求可以打包在一个数组中发送
[
{
"jsonrpc": "2.0",
"method": "sum",
"params": [1, 2, 3],
"id": 1
},
{
"jsonrpc": "2.0",
"method": "multiply",
"params": [4, 5],
"id": 2
}
]
// 批量响应
[
{
"jsonrpc": "2.0",
"result": 6,
"id": 1
},
{
"jsonrpc": "2.0",
"result": 20,
"id": 2
}
]
```
4. 实际应用示例(以 Motrix/aria2 为例):
```javascript
// 客户端实现
class JsonRpcClient {
constructor(url) {
this.url = url;
this.id = 0;
}
async call(method, params) {
const request = {
jsonrpc: "2.0",
method: method,
params: params,
id: ++this.id
};
const response = await fetch(this.url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
});
return response.json();
}
}
// 使用示例
const client = new JsonRpcClient('http://localhost:16800/jsonrpc');
// 添加下载任务
await client.call('aria2.addUri', [
['http://example.com/file.zip']
]);
// 查询下载状态
const status = await client.call('aria2.tellStatus', ['gid123']);
```
5. 错误处理:
```javascript
// 预定义的错误码
const ERROR_CODES = {
PARSE_ERROR: -32700, // 解析错误
INVALID_REQUEST: -32600, // 无效请求
METHOD_NOT_FOUND: -32601, // 方法不存在
INVALID_PARAMS: -32602, // 无效参数
INTERNAL_ERROR: -32603 // 内部错误
};
// 错误处理示例
try {
const result = await client.call('nonexistentMethod', []);
} catch (error) {
if (error.code === -32601) {
console.error('Method not found');
}
}
```
6. WebSocket 实现:
```javascript
class JsonRpcWebSocketClient {
constructor(url) {
this.ws = new WebSocket(url);
this.id = 0;
this.callbacks = new Map();
this.ws.onmessage = (event) => {
const response = JSON.parse(event.data);
// 处理响应
if (response.id && this.callbacks.has(response.id)) {
const callback = this.callbacks.get(response.id);
this.callbacks.delete(response.id);
callback(response.error, response.result);
}
// 处理通知
else if (!response.id) {
this.handleNotification(response);
}
};
}
call(method, params) {
return new Promise((resolve, reject) => {
const id = ++this.id;
this.callbacks.set(id, (error, result) => {
if (error) reject(error);
else resolve(result);
});
this.ws.send(JSON.stringify({
jsonrpc: "2.0",
method: method,
params: params,
id: id
}));
});
}
handleNotification(notification) {
// 处理服务器推送的通知
console.log('Received notification:', notification);
}
}
```
7. 主要特点:
- 简单易用:使用 JSON 格式,易于理解和调试
- 语言无关:可以在任何支持 JSON 的语言中使用
- 传输协议无关:可以通过 HTTP、WebSocket 等传输
- 支持双向通信:通过通知机制支持服务器推送
- 支持批量操作:可以在一个请求中包含多个调用
8. 使用建议:
- 为方法提供明确的命名空间(如 aria2.addUri)
- 合理使用批量请求减少网络往返
- 实现错误重试和超时处理
- 考虑并发请求的处理
- 合理使用通知机制降低服务器负载
欢迎光临 firemail (http://firemail.wang:8088/)
Powered by Discuz! X3