websocket是im系统长连接的通信骨架,需构建传输层(连接管理)、协议层(消息编解码)、业务层(路由鉴权)和存储层(mysql/redis/kafka)四层架构,并通过redis映射、消息总线、ack重试、幂等设计及小程序适配等机制保障高并发与可靠性。

WebSocket 是即时通讯系统里最常用也最可靠的长连接技术,它不是“开个连接就能用”的简单工具,而是一整套通信骨架的起点。真正决定 IM 系统是否稳定、可扩展、易维护的,是围绕 WebSocket 构建的分层架构和关键机制设计。
分层解耦:四层结构支撑可演进能力
成熟 IM 系统普遍采用清晰的四层架构,每层职责分明,避免逻辑混杂:
- 传输层:专注 WebSocket 连接生命周期管理——握手校验、心跳保活(如每30秒 ping/pong)、断线自动重连、连接异常兜底;不处理业务,只确保通道可用
- 协议层:定义消息“怎么编”和“怎么解”。主流方案是 JSON(开发快、调试直观)或 Protobuf(体积小、解析快),需统一字段规范(如 type、from、to、seq、timestamp)
- 业务层:承载核心逻辑——用户鉴权(JWT 或 token 校验)、消息路由(私聊转发、群聊广播)、已读回执、撤回处理、离线消息暂存与投递
- 存储层:按需分用——MySQL 存用户关系和消息元数据,Redis 缓存在线状态与未读数,RabbitMQ/Kafka 做高并发消息缓冲,避免服务雪崩
连接管理:从单机到分布式的关键跃迁
小程序或 Web 端直连 WebSocket 服务时,单节点容易成为瓶颈。要支持万级并发,必须解决连接状态跨节点同步问题:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 用 Redis 维护全局在线用户映射表(如 hash 结构:user:1001 → ws://node2:8080/conn-id-abc),所有节点都能查到目标用户在哪台机器上
- 引入消息总线(如 Redis Pub/Sub 或 Kafka),当 A 用户发消息给 B,服务端不直接推送,而是发布到 topic,B 所在节点订阅后主动投递
- Netty 或 Spring Boot + WebSocket 服务需注册到 Nacos/Eureka,网关按负载均衡策略将新连接分发到不同实例,同时保证同一用户的后续请求路由到相同节点(会话粘性)
消息可靠性:不只是“发出去”,更要“送到位”
WebSocket 本身不保证消息必达。实际生产中必须叠加应用层保障机制:
- 客户端消息队列:用户未登录或连接未建立时,待发消息先入本地缓存(小程序可用 storage,App 可用数据库),连接恢复后按序重发
- 服务端 ACK + 重试:每条消息带唯一 seq,接收方成功处理后返回 ack;服务端超时未收到 ack,则触发重试(建议最多 3 次),失败后写入离线队列
- 幂等设计:消息体含时间戳 + 客户端生成的 msgId,服务端入库前先查 Redis 是否已处理过该 msgId,防止重复消费
前端适配:小程序与多端协同的特别考量
微信小程序对 WebSocket 有明确限制(如仅支持 wss、最大并发连接数、内存占用敏感),架构设计需针对性优化:
- 通信模块抽象为接口(如 IIMHandler),底层用 web-socket-handler-imp.js 封装小程序 wx.connectSocket API,上层业务完全无感
- 语音、图片等大消息不走 WebSocket 直传,改为先上传 CDN 获取 URL,再通过 WebSocket 发送轻量文本消息(含 URL 和元信息)
- UI 层与消息管理层分离——聊天界面只负责渲染,消息类型(文本/语音/表情)由独立 manager 类处理,新增类型无需改 UI 代码










