不能直接用 net/http + gorilla/websocket 上生产,因为二者不处理连接管理、心跳保活、并发写安全、多端互斥、离线兜底五件事;Go-Zero 通过微服务拆分明确职责边界;Gotify 仅适用于弱送达要求的内部通知;企业微信 SDK 严格受限于应用消息接口与通讯录权限。

为什么不能直接用 net/http + gorilla/websocket 上生产
因为连接管理、心跳保活、并发写安全、多端互斥、离线兜底这五件事,net/http 和 gorilla/websocket 都不负责——它们只管“连上”和“收发字节”,其余全是业务逻辑。
常见现象包括:用户切后台 5 分钟后连接静默断开但服务端无感知;同一用户手机+PC 同时在线,消息重复推;高并发推送时 panic: concurrent write to websocket connection;HTTP 接口触发推送,目标用户离线,直接卡住整个 handler。
- 必须自己实现 TCP 层 + 应用层双心跳:
conn.SetPingHandler处理websocket.PingMessage,同时客户端每 30s 主动发{"type":"pulse"},服务端回{"type":"pong"},连续 2 次未收到就conn.Close() -
http.Request.Context().Done()在 WebSocket 升级后失效,不能用来判断断连 - 所有写操作必须串行:用
chan []byte做写队列,单 goroutine 顺序调用conn.WriteMessage,写前检查conn.IsClosed() - 用户 ID 到连接的映射要用
map[string][]*Client+sync.RWMutex,新连接建立时主动 close 所有旧连接,不能等超时或 GC
Go-Zero 怎么简化消息推送的微服务拆分
Go-Zero 不是帮你少写代码,而是把“谁该管什么”这件事划清楚。比如 user 服务只管认证和在线状态更新;message 服务只管消息格式校验、路由决策、落库;push 服务只管连接管理、实时下发、离线兜底。
它通过 goctl 自动生成 RPC 接口定义和 client/stub 代码,避免手写序列化/反序列化和错误码透传。比如 message.Push 方法被调用时,push 服务拿到用户 ID 后,直接查 user 服务获取当前活跃连接列表,再批量投递——RPC 调用天然带超时、重试、熔断。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 连接状态建议存 Redis,但
DEL连接 key 和PUBLISH离线事件之间有竞态,必须用 Lua 脚本保证原子性 - 离线消息不能只写 MySQL,要加内存环形缓冲(如
ringbuffer包)做写缓冲,再异步落库,否则高并发写 DB 直接拖垮 - 广播类推送(如全量通知)必须拆任务:
center服务把目标用户分片,每个分片由独立 goroutine 调用push服务,避免单点阻塞
Gotify 适合什么场景,又容易在哪翻车
Gotify 是开箱即用的轻量级推送服务,不是框架,也不解决“用户身份绑定”“消息幂等”“多端互斥”这些事。它适合内部工具通知、CI/CD 结果推送、运维告警这类“发了就行、不强求送达、不关心谁发给谁”的场景。
典型翻车点:用 gotify/server 的 token 当作业务用户凭证;在 Android 客户端里硬编码 server 地址导致无法灰度;把 priority=5 当作消息重要性分级,却没配好客户端通知渠道权限。
- App token 是应用级凭证,不是用户级——多个用户共用一个 App 就无法区分接收人
- Android 客户端依赖系统通知权限,
priority只影响通知栏展示顺序,不控制是否弹窗或响铃 - Gotify 自带 Web UI 和 CLI,但没有提供标准 OAuth2 登录入口,无法对接企业统一身份认证
- 它的 REST API 不带签名机制,暴露在公网时必须加反向代理(如 Nginx)做 Basic Auth 或 JWT 校验
企业微信 SDK 的合规边界在哪
waro163/wechat_bot_sdk 封装的是企业微信「应用消息」接口,不是个人微信协议。这意味着它只能向企业通讯录里的成员推送,且必须走企业微信后台配置的应用 AgentId 和 Secret,不能绕过审核发营销消息。
它不支持“模拟登录”“抓取聊天记录”“自动加好友”,也不处理用户主动发送的消息(除非你额外实现回调服务器并验证签名)。它的价值是把 AccessToken 自动刷新、消息体 JSON 组装、HTTP 错误重试这些脏活包掉,让你专注业务逻辑。
- 消息类型限制明确:支持
text、markdown、image、file、news(图文),不支持语音、位置、小程序卡片 - 发送频率受企业微信限流:普通应用默认 200 次/分钟,需在后台申请提额
- 接收用户回复需单独配置回调 URL,并在服务端实现签名验证(
msg_signature、timestamp、nonce三参数校验) - 如果企业微信管理员禁用了“外部联系人”或“客户联系”权限,
userid必须是通讯录内真实员工 ID,不能是客户微信 openid
map 更新、Redis key 过期、数据库状态同步之间亲手缝合。

















