WebSocket实时通信
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @kunlungrowth/websocket-realtime。
技能介绍
要解决的问题
WebSocket 看起来只是一行 new WebSocket(url),真正落到生产环境却处处是坑:移动端网络切换导致的静默断线、ping/pong 没做导致的半开连接、重连风暴把服务端连接数打满、多实例部署时消息跨节点丢失。这个技能针对的就是这类工程问题——不是讲协议基础,而是给出连接生命周期里每个环节的具体参数和策略。
核心能力与工作流
技能按五个步骤组织,每一步都有可执行的默认值:
- 选型:不预设答案。
原生 WebSocket无依赖、底层控制强,但重连/心跳/ack 全要自己写;Socket.IO内置重连、心跳、房间和 HTTP 长轮询回退,适合聊天和协作类应用;SSE是单向推送,做通知和日志流时协议更简单、自动重连、不需要特殊代理配置。 - 连接管理:服务端每 30s 发 ping,客户端 10s 内回 pong,超时主动断开清理资源;客户端 60s 收不到任何消息即判定断线。服务端用
Map维护活跃连接以支持单用户多设备;收到SIGTERM时按「停新连接 → 通知客户端 reconnect → 等 5s → 断开」的顺序优雅关闭。 - 断线重连:指数退避
min(30s, 2^N),重连后携带lastEventId或时间戳让服务端补偿失联期间的消息;监听navigator.onLine的online事件跳过退避立即重连;visibilitychange切后台时降低心跳频率,回前台时检查连接状态。 - 房间广播:服务端维护
Map<roomId, Set<connId>>,提供join/leave/broadcast(roomId, message, excludeConnId?)三个原语,广播时可排除发送者。 - 水平扩展:单机很简单,多实例才见真章。Socket.IO 用 Redis Adapter 打通跨实例 socket;自定义实现走 Redis Pub/Sub 或 Kafka 同步消息;网关层用
ip_hash或 JWT 携带路由信息做连接粘性;房间状态外置到 Redis,但连接对象留在实例内存。
适用边界
一次性通知请直接用 Web Push 或轮询,没必要维持长连接;大文件传输应走 HTTP chunked upload,不是这个技能的覆盖范围。另外,如果团队没有运维 Redis Pub/Sub 和 sticky session 的现成经验,先跑通单机版本再扩展,否则排查链路会比连接本身更难。
使用场景
- 写聊天室时需要决定用原生 WebSocket、Socket.IO 还是 SSE,并确定心跳间隔、重连退避等参数。
- 线上 WebSocket 频繁断线,需要排查是心跳超时未清理半开连接,还是客户端重连逻辑有 bug。
- 多实例部署后消息只发到当前节点,需要设计 Redis Adapter、Redis Pub/Sub 和 sticky session。
- 给协作编辑或数据看板加实时推送,需要确定房间模型、广播时是否排除发送者以及消息补偿方式。
适合人员
- 负责聊天、通知或协作功能的后端工程师,需要把不稳定的长连接改造成可保活、可重连的方案。
- 维护实时数据看板的全栈工程师,要在多实例部署下保证房间广播不丢消息、不重复。
- 正在选型实时通信方案的技术负责人,需要对比原生 WebSocket、Socket.IO 与 SSE 的边界。
- 遇到移动端切网络后静默断线问题的客户端工程师,需要实现指数退避重连与断线期消息补偿。