WebSocket需服务端自行实现房间与私聊逻辑:用Map管理clients和rooms,按消息type字段路由广播或定向发送,客户端遵循统一JSON协议收发,服务端校验身份与在线状态确保安全。

WebSocket 本身不内置房间或私聊概念,需要在服务端维护连接状态和消息路由逻辑。关键在于:服务端要能识别用户、管理房间、区分广播与定向发送;客户端则按约定格式收发消息。
服务端:用 Map 管理连接与房间
Node.js(如使用 ws 库)中,可创建两个 Map:
- clients:以唯一 ID(如 userId 或 socket.id)为键,存储 socket 实例,用于私聊定向发送
- rooms:以房间名(如 "room-101")为键,值是该房间内所有 socket ID 的 Set 或数组,用于群发
用户加入房间时,把其 socket ID 加入对应 room 的集合;断开时及时清理。注意避免内存泄漏——每次连接关闭都要从 clients 和所有 rooms 中移除该 ID。
消息协议设计:统一格式区分类型
约定客户端发送的 JSON 消息结构,例如:
立即学习“Java免费学习笔记(深入)”;
{
"type": "join", // join / leave / chat / private
"room": "general",
"to": "user233", // 私聊目标 ID(仅 type === "private" 时存在)
"content": "你好",
"from": "user123"
}
服务端根据 type 字段分发:
- type 为 "chat" 且带 room → 向该 room 所有成员广播(排除 sender 自己)
- type 为 "private" 且带 to → 查 clients.get(to),存在则 send 给对方
- type 为 "join" → 将当前 socket ID 加入 rooms.get(room),并通知房间内其他人
客户端:按类型处理收发逻辑
建立连接后,发送消息前先构造符合协议的对象:
- 群聊:{ type: "chat", room: "tech", content: "今天学 WebSocket" }
- 私聊:{ type: "private", to: "alice", content: "在吗?" }
接收消息时,检查 type 字段决定如何展示:
- type === "chat" → 显示在对应房间聊天区
- type === "private" → 显示在与 to 用户的独立对话窗口
- 可额外加字段如 timestamp、avatar,由服务端或客户端生成
安全与健壮性要点
不要完全信任客户端传来的 from 或 to 字段:
- 服务端应以 socket 关联的用户身份(如登录后存的 userId)为准,忽略客户端伪造的 from
- 私聊前校验 to 是否在线(clients.has(to)),否则返回错误提示
- 房间名、用户 ID 建议服务端生成或严格校验格式,防止注入或遍历攻击
- 大房间群发建议用 for...of 遍历 Set,避免 forEach + await 导致阻塞
不复杂但容易忽略。


















