go构建websocket服务端核心是稳长连接、控广播、防泄漏:需显式校验checkorigin、设读写缓冲与超时、每连接配独立读写goroutine并加心跳、用sync.map管理连接、广播前过滤无效连接,上线前须压测、断网验证与写超时防护。

Go语言构建WebSocket服务端推送,核心在于用好goroutine并发模型和gorilla/websocket库的连接管理能力。重点不是堆功能,而是稳住长连接、控住广播逻辑、防住资源泄漏。
连接升级与基础握手要安全可控
客户端发起HTTP请求带Upgrade头,服务器必须显式响应101状态码完成协议切换。使用gorilla/websocket.Upgrader时,CheckOrigin务必校验来源,生产环境不能设为return true;同时设置读写缓冲区大小(如1024或4096字节)、超时时间(ReadTimeout/WriteTimeout)和最大消息长度(SetReadLimit),避免恶意大包拖垮服务。
每个连接配一个读写协程,避免阻塞
不要在一个goroutine里混着读和写——这会导致消息积压或死锁。标准做法是:
- 为每个连接启动两个独立goroutine:一个
readPump专注读取消息并分发,另一个writePump从channel取数据发送 -
writePump中嵌入心跳(Ping/Pong),用time.Ticker定期发Ping帧,收到Pong自动刷新读超时 - 读写都加
defer conn.Close(),并在出错时通知对方关闭帧
消息广播需解耦连接管理与业务逻辑
直接遍历所有连接调WriteMessage看似简单,但高并发下易成瓶颈。推荐方式:
- 用
sync.Map或带锁map存活跃连接,key可为用户ID或会话ID - 广播前先过滤无效连接(检查
conn.IsClosed()或捕获write error) - 对群聊类场景,按“房间”或“频道”做二级索引,避免全量扫描
- 敏感操作(如系统通知)走独立HTTP接口触发推送,不依赖前端主动发指令
上线前必须做的三件事
很多问题只在真实压力下暴露:
- 用
ab或hey模拟数百并发连接,观察内存增长是否线性、GC频率是否异常 - 强制断网、杀客户端进程,验证服务端能否及时检测连接中断并清理资源
- 在
WriteMessage前加conn.SetWriteDeadline,防止慢连接卡住整个goroutine
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











