Golang WebSocket广播需安全维护连接集合并异步分发消息:用sync.RWMutex保护clients map,快照连接切片广播;通过broadcast channel解耦收发,设写 deadline、recover异常、启心跳检测失效连接。

在Golang中实现WebSocket消息广播,核心是**安全维护在线连接集合 + 异步分发消息**。不依赖第三方服务,用标准库配合 gorilla/websocket 就能稳定支撑百至千级并发。
管理客户端连接:用 map + 读写锁保障并发安全
所有活跃连接必须集中存储,并确保多协程读写不冲突:
- 声明
clients map[*websocket.Conn]bool存储当前连接 - 用
sync.RWMutex包裹增删操作(如新连接加入、断开时删除) - 升级HTTP连接后立即注册:
clients[conn] = true,并在 defer 中清理 - 避免直接遍历原始 map —— 广播前先用
RLock()快照一份连接切片,防止遍历时被修改
广播消息:通过 channel 解耦接收与发送
不让读消息的协程直接遍历连接,否则一个慢连接会拖垮所有人:
- 定义全局
broadcast chan []byte作为消息中转站 - 启动独立 goroutine 持续监听该 channel:
for msg := range broadcast { ... } - 每次收到消息,遍历快照连接列表,调用
conn.WriteMessage(websocket.TextMessage, msg) - 为每个写操作设置
conn.SetWriteDeadline(time.Now().Add(10 * time.Second)),防阻塞
处理异常连接:自动识别并清理失效连接
客户端断网、关页、超时都是常态,不能靠等待 Close 通知:
立即学习“go语言免费学习笔记(深入)”;
- 在
WriteMessage外加recover(),捕获 panic(如连接已关闭) - 检查错误是否为
websocket.ErrCloseSent或io.EOF,是则立即conn.Close()并从 clients 中删除 - 启用心跳机制:每 30 秒发一次
ping,客户端需回pong;超时未响应则主动断开 - 读协程里用
conn.SetReadDeadline配合conn.ReadMessage,超时即视为离线
前端配合:简单可靠即可完成闭环
浏览器端无需复杂逻辑,原生 WebSocket API 足够:
- 创建连接:
const ws = new WebSocket("ws://localhost:8080/ws") - 发送消息:
ws.send(JSON.stringify({type:"msg", content:"hello"})) - 接收广播:
ws.onmessage = e => console.log("收到:", JSON.parse(e.data)) - 重连建议:监听
onclose,延迟 1–3 秒后尝试重建连接










