跳转到主内容
极星编程网:以代码为星,赴技术山海!

WebSocket怎么实现私聊和群聊功能 WebSocket消息定向推送逻辑【源码】

私聊和群聊的核心差异在于服务端消息路由逻辑而非协议层;需通过clients映射表和targetId字段实现定向分发,严格校验type、targetId、连接状态及fromId来源。 私聊和群聊的核心差异不在协议层,而在服务端消息路由逻辑——WebSocket本身不区分私聊/群聊,全靠你用
clients
映射表和
targetId
字段做定向分发。 客户端发消息时必须带明确的
type
和
targetId
很多初学者卡在“消息发出去但对方收不到”,根本原因是前端没按约定结构发送JSON。服务端只认
type
(
"private"
或
"group"
)和
targetId
(私聊填对方ID,群聊可填
"all"
或群组标识),其他字段全被忽略。
type === "private"
时,
targetId
必须是服务端已存入
clients
Map里的有效用户ID,且
clients.get(targetId)?.readyState === WebSocket.OPEN
type === "group"
时,服务端需遍历
clients.values()
,跳过发送方自身;若用群组ID管理,得额外维护
groupMembers: Map>
前端发送前务必校验
targetId
非空、非
undefined
,否则
clients.get(undefined)
返回
undefined
,后续
.send()
直接报错
clients
Map必须实时同步连接状态 WebSocket连接断开时,
clients
里残留无效引用会导致私聊失败或崩溃。不能只靠
connection
事件注册,还必须监听
close
和
error
事件清理。 WebSocket 8.21.0 WebSocket 8.21.0 是一个高性能、双向实时通信协议库的更新版本。它基于标准 WebSocket 协议,提供稳定、低延迟的全双工数据通道,适用于实时聊天、游戏、金融行情等场景。该版本优化了连接稳定性与重连机制,增强了消息压缩与安全校验功能,并改进对多种后端框架的兼容性。开发者可借助简洁的 API 快速集成实时推送服务,显著降低资源占用并提升并发处理效率。 下载 每个
ws
实例绑定
ws.on("close", () => clients.delete(userId))
,
userId
需提前挂载到
ws
上(如
ws.userId = userId
),避免闭包丢失 不要用
setInterval
轮询心跳——既增加服务器负担,又无法及时感知断连;改用
ws.isAlive = true
+
ping
事件回调标记 广播在线列表时,只遍历
clients.values()
并过滤
readyState === WebSocket.OPEN
的连接,否则
ws.send()
会抛
WebSocket is not open
群聊广播别直接
for...of clients.values()
看似简单粗暴的遍历,在高并发下容易阻塞Event Loop。当在线用户超200人,单次群聊广播可能耗时几十毫秒,导致后续消息积压。 用
Array.from(clients.values())
先转数组,再用
forEach
而非
for...of
,减少迭代器开销 对每个
ws
调用
send()
前加
if (ws.readyState !== WebSocket.OPEN) continue
,避免无意义错误捕获 若需支持离线消息,
send()
失败后应记录到
offlineQueue.set(targetId, [...queue, msg])
,而非当场重试 最容易被忽略的是:私聊消息的
fromId
字段必须由服务端生成并注入,绝不能信任客户端传来的
userId
。攻击者只要伪造
fromId
就能冒充他人发消息——这个校验点一旦漏掉,整个私聊功能就失去可信基础。

相关文章