websocket可作为底层传输通道实现前端类rpc通信,需定义含id、method、params及type字段的json协议,封装rpcclient管理请求响应匹配与promise生命周期,并支持超时控制和类型安全。

WebSocket 本身不提供 RPC 功能,但可以作为底层传输通道,配合自定义协议和客户端/服务端协同设计,在前端实现类 RPC 的通信模式——即“调用远程函数,等待返回结果”。核心在于请求-响应匹配、消息序列化、异步回调管理。
定义轻量级 RPC 协议格式
需要约定一个结构清晰的 JSON 消息格式,包含唯一 ID、方法名、参数、类型标识(请求/响应/错误):
-
请求消息:
{ "id": "req_123", "method": "getUserInfo", "params": [1001], "type": "call" } -
成功响应:
{ "id": "req_123", "result": { "name": "Alice", "age": 28 }, "type": "result" } -
错误响应:
{ "id": "req_123", "error": { "code": 404, "message": "User not found" }, "type": "error" }
前端每次发起调用时生成唯一 id(推荐用 crypto.randomUUID() 或时间戳+随机数),并缓存该 ID 对应的 Promise resolve/reject 函数。
封装 WebSocket 为可调用的 RPC 客户端
创建一个类(如 RpcClient),内部维护连接状态、待处理请求 Map 和消息分发逻辑:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 连接建立后监听
message事件,解析 JSON,根据id查找对应 Promise 处理器 - 提供
call(method, ...args)方法:生成 ID → 构造请求 → 发送 → 返回 Promise - 自动重连机制(可选):监听
onclose,延迟重试并清空未完成请求(或标记为 rejected)
示例关键代码片段:
class RpcClient {
constructor(url) {
this.url = url;
this.ws = null;
this.pendingCalls = new Map(); // id → { resolve, reject }
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onmessage = (e) => {
const data = JSON.parse(e.data);
const { id, type, result, error } = data;
const handler = this.pendingCalls.get(id);
if (!handler) return;
this.pendingCalls.delete(id);
if (type === 'result') handler.resolve(result);
else if (type === 'error') handler.reject(error);
};
}
call(method, ...params) {
return new Promise((resolve, reject) => {
const id = crypto.randomUUID();
this.pendingCalls.set(id, { resolve, reject });
this.ws.send(JSON.stringify({
id, method, params, type: 'call'
}));
});
}
}
前端使用方式:像调用本地函数一样
初始化客户端后,所有远程方法调用都返回 Promise,支持 await 或 .then():
const user = await rpc.call('getUserInfo', 1001);rpc.call('updateProfile', { name: 'Bob' }).then(console.log).catch(console.error);
可进一步封装成带 TypeScript 类型提示的代理对象(例如用 Proxy 拦截方法调用),让 IDE 支持自动补全和类型检查。
注意事项与健壮性补充
- 超时控制:Promise 内部启动定时器,一定时间未收到响应则 reject,避免悬停请求
- 序列化限制:只传可 JSON 序列化的参数;函数、Date、Map 等需提前转换(如 Date → ISO 字符串)
- 服务端配合:后端需按相同协议解析请求、执行对应函数、原路返回带相同 ID 的响应
- 并发安全:每个请求 ID 独立,天然支持多路并发,无需加锁
不复杂但容易忽略。只要前后端对齐协议、前端管好 Promise 生命周期,WebSocket 上的 RPC 就能稳定高效运行。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










