|
在 Motrix 的实现中,JSON-RPC 和 WebSocket 的关系是:JSON-RPC 是通信协议(内容格式),WebSocket 是传输协议(传输通道)。让我详细解释它们的区别和联系:
1. 区别:
```javascript
// JSON-RPC: 定义了请求和响应的数据格式
{
"jsonrpc": "2.0",
"method": "aria2.addUri",
"params": [["http://example.com/file.zip"]],
"id": 1
}
// WebSocket: 定义了如何建立和维护连接
ws://localhost:16800/jsonrpc
```
- JSON-RPC:
- 是一个内容协议,定义数据如何组织和格式化
- 规定了方法调用的格式(method、params、id等)
- 与传输方式无关,可以用 HTTP 或 WebSocket 传输
- WebSocket:
- 是一个传输协议,定义数据如何传输
- 提供全双工通信通道
- 保持长连接,减少连接开销
- 可以传输任意格式数据,不仅限于 JSON-RPC
2. 联系:
```typescript
// Motrix 中典型的 WebSocket 客户端实现
class Aria2Client {
private ws: WebSocket;
constructor() {
// 建立 WebSocket 连接
this.ws = new WebSocket('ws://localhost:16800/jsonrpc');
// 监听 WebSocket 消息
this.ws.onmessage = (event) => {
const message = JSON.parse(event.data);
// 处理 JSON-RPC 消息
this.handleJsonRpcMessage(message);
};
}
// 发送 JSON-RPC 请求
async addUri(uri: string) {
const request = {
jsonrpc: '2.0',
method: 'aria2.addUri',
params: [[uri]],
id: this.generateId()
};
this.ws.send(JSON.stringify(request));
}
}
```
3. 为什么一起使用:
- 优势互补:
- JSON-RPC 提供规范的远程调用格式
- WebSocket 提供高效的传输通道
- 实际应用场景:
```javascript
// 1. 下载任务添加(客户端到服务端)
-> {
"jsonrpc": "2.0",
"method": "aria2.addUri",
"params": [["http://example.com/file.zip"]],
"id": 1
}
// 2. 进度通知(服务端到客户端)
<- {
"jsonrpc": "2.0",
"method": "aria2.onDownloadProgress",
"params": [{
"gid": "xxx",
"completedLength": "1024",
"totalLength": "2048"
}]
}
```
4. 替代方案:
- HTTP + JSON-RPC:
- 需要客户端轮询获取进度
- 连接开销大
- 实时性差
```javascript
// HTTP 轮询方式
async function pollProgress() {
while (true) {
const response = await fetch('http://localhost:16800/jsonrpc', {
method: 'POST',
body: JSON.stringify({
jsonrpc: '2.0',
method: 'aria2.tellActive',
id: 1
})
});
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
```
- WebSocket + 自定义协议:
- 缺少标准化的方法调用格式
- 需要自己设计协议格式
- 不利于与其他工具集成
所以 Motrix 选择 WebSocket + JSON-RPC 的组合是一个很好的选择,既保证了实时性和效率,又具有良好的可维护性和扩展性。
|
|