WebSocket本身不提供点对点能力,需服务端通过用户身份绑定、在线状态管理、消息路由实现私聊;客户端发消息须带to字段,服务端查表后单播给目标用户socket。

WebSocket 本身不直接提供“点对点”能力,它只是建立客户端与服务器之间的**全双工长连接**。真正的私聊(即用户 A 发消息只给用户 B,其他人收不到)必须由**服务端逻辑控制消息路由**来实现。关键在于:服务端要识别用户身份、维护在线状态、并按目标用户精准投递消息。
用户身份绑定与在线状态管理
客户端连接 WebSocket 后,必须向服务端发送自己的唯一标识(如 userId 或 token),服务端据此将 socket 实例与用户关联起来。常用做法是用 Map 或对象缓存映射关系:
- 连接建立后,要求客户端立即发送登录凭证(如 JWT 或 userId)
- 服务端验证通过,把 socket → userId 存入内存 Map(如
onlineUsers.set(userId, socket)) - 监听
close或error事件,及时从 Map 中删除离线用户
消息格式设计:明确收件人
客户端发送的消息不能只是纯文本,需携带接收方标识。建议统一使用 JSON 格式,包含必要字段:
-
type:如
"private",区分群聊/私聊/系统消息 - to:目标用户 ID(必填)
- from:发送方 ID(服务端可自行添加,避免客户端伪造)
- content:消息正文
例如:{"type":"private","to":"user102","content":"你好呀"}
立即学习“Java免费学习笔记(深入)”;
服务端精准转发:查表 + 单播
收到私聊消息后,服务端不做广播,而是查找目标用户是否在线,并只向其 socket 发送:
- 解析消息,提取
to字段 - 查
onlineUsers.get(to)获取对应 socket - 若存在且连接正常(
socket.readyState === 1),调用socket.send() - 若目标不在线,可存入数据库做离线消息,待其上线再推送
客户端收发逻辑:区分消息类型
前端需根据消息 type 和 to/from 字段决定如何展示:
- 收到消息时检查
data.to === currentUserId,确认是发给自己的 - 发送私聊前,确保已知对方 userId(比如从聊天列表点击进入会话)
- UI 上需隔离不同会话,每条消息标注发送者昵称和时间
注意:不要在前端靠“房间名”或“URL 参数”模拟点对点——那本质仍是广播过滤,不安全也不可靠。


















