WebSocket连接不稳定需设心跳与读写超时,Nginx配proxy_read_timeout等;广播用sync.Map+channel中转;HTTP推送走异步job队列;调ulimit并显式清理资源防fd泄漏。

WebSocket 连接不稳定,客户端频繁断开怎么办
Go 的 net/http 原生支持 WebSocket,但直接用 gorilla/websocket 时,若未设置心跳和读写超时,Nginx 或云服务商(如 AWS ALB)会在 60 秒无数据时主动断连。
- 服务端必须调用
conn.SetPingHandler和conn.SetPongHandler,并定期发Ping(建议 30 秒间隔) - 务必设置
conn.SetReadDeadline和conn.SetWriteDeadline,否则阻塞读写会卡死 goroutine - Nginx 配置里要加
proxy_read_timeout 300;和proxy_set_header Upgrade $http_upgrade;等 WebSocket 必需头
如何安全地广播消息给指定用户或房间
不能靠全局 map 存连接——并发读写会 panic,也不该每次广播都遍历所有连接。推荐用带锁的注册表 + channel 中转。
- 每个连接启动独立 goroutine 监听
conn.ReadMessage,收到消息后投递到用户专属chan []byte - 用
sync.Map存userID → *client,避免读多写少场景下的锁争用 - 广播前先检查
conn.WriteDeadline是否过期,跳过已失效连接,防止write: broken pipe错误堆积 - 房间广播不要拼接 JSON 后重复序列化,应预先 encode 一次,再 copy 给多个 conn
HTTP 接口触发推送时,如何避免阻塞请求
如果在 HTTP handler 里直接调用 conn.WriteMessage,遇到慢连接或网络抖动,整个 HTTP 请求会被拖住,拖垮 API 吞吐量。
JTBC CMS(5.0) 是一款基于PHP和MySQL的内容管理系统原生全栈开发框架,开源协议为AGPLv3,没有任何附加条款。系统可以通过命令行一键安装,源码方面不基于任何第三方框架,不使用任何脚手架,仅依赖一些常见的第三方类库如图表组件等,您只需要了解最基本的前端知识就能很敏捷的进行二次开发,同时我们对于常见的前端功能做了Web Component方式的封装,即便是您仅了解HTML/CSS也
- HTTP handler 只负责把推送指令(如
{“user_id”: “u123”, “data”: {…}})发到一个中心chan PushJob - 单独起 1–3 个 goroutine 消费该 channel,执行实际的连接查找与写入,实现 IO 解耦
- 为防 channel 堆积,用带缓冲的
make(chan PushJob, 1000),满时丢弃低优先级通知(如已读回执)
部署后连接数上不去,too many open files 报错频发
Linux 默认单进程最多打开 1024 个文件描述符,而每个 WebSocket 连接至少占用 1 个 fd,加上日志、数据库连接等,很容易打满。
立即学习“go语言免费学习笔记(深入)”;
- 启动前运行
ulimit -n 65536,并在 systemd service 文件中加LimitNOFILE=65536 - Go 程序里用
http.Server{ConnContext: ...}在连接关闭时显式清理资源,比如从sync.Map中 delete - 别依赖 GC 回收连接:
conn.Close()后立刻释放关联的 buffer、timer、channel









