WebSocket命令模式通过解析消息为“命令名+参数”并路由至处理器实现解耦,采用统一JSON结构{cmd,data,id},用Map注册处理器,支持中间件、通配符匹配、错误隔离与响应封装。

WebSocket 实现命令模式的消息分发,核心是把收到的每条消息解析为“命令名 + 参数”,再路由到对应的处理器函数,避免用一堆 if-else 或 switch 判断类型。
定义统一消息结构
客户端和服务端约定一个简单、可扩展的消息格式,比如:
{
"cmd": "user.login",
"data": { "username": "alice", "token": "xxx" },
"id": "req_123"
}
其中 cmd 是命令标识符(推荐用点号分隔的命名空间形式),data 是业务参数,id 可用于响应匹配或幂等控制。
注册命令处理器
用 Map 或普通对象集中管理命令与处理函数的映射关系,支持动态注册:
立即学习“Java免费学习笔记(深入)”;
- 按模块组织:如
"user.login"、"chat.send"、"room.join" - 每个处理器接收
data和ws(当前连接实例),可异步执行并主动推送响应 - 支持中间件:比如鉴权、日志、参数校验,统一在分发前运行
实现分发器
收到消息后解析 JSON,提取 cmd,查找对应处理器并执行:
const handlers = new Map();
// 注册示例
handlers.set('user.login', async (data, ws) => {
const user = await auth(data.token);
ws.userId = user.id;
ws.send(JSON.stringify({ cmd: 'user.login.ok', data: user }));
});
// 分发逻辑
ws.on('message', (raw) => {
try {
const msg = JSON.parse(raw);
const handler = handlers.get(msg.cmd);
if (handler) handler(msg.data, ws).catch(err => console.error(err));
else ws.send(JSON.stringify({ cmd: 'error', data: { code: 'UNKNOWN_CMD' } }));
} catch (e) {
ws.send(JSON.stringify({ cmd: 'error', data: { code: 'PARSE_FAIL' } }));
}
});
增强健壮性的小技巧
- 命令名做标准化处理:统一转小写、过滤非法字符,防止大小写或空格导致匹配失败
- 支持通配符或前缀匹配:如
"user.*"匹配所有用户相关命令,适合权限或日志拦截 - 错误隔离:每个命令独立 try/catch,不因一个失败阻塞其他命令处理
- 响应封装:提供统一的
reply(cmd, data)方法,自动带上请求id,方便前端关联请求/响应


















