type
status
date
slug
summary
tags
category
icon
password

polling, long polling 和 websocket机制来通信
🔄 Polling(轮询)
工作原理
客户端定时主动向服务器发请求,就像你每隔几分钟问朋友"有新消息吗?"
特点分析
优势:
- 实现简单:就是普通的HTTP请求,前后端都好理解
- 兼容性好:任何支持HTTP的环境都能用
- 服务器无状态:每次请求都是独立的,服务器压力相对可控
劣势:
- 延迟高:最坏情况下延迟 = 轮询间隔时间
- 资源浪费:大部分请求都是"没有新消息"的无效请求
- 服务器压力大:大量客户端同时轮询会产生很多无意义的请求
适用场景
股票价格显示:
- 价格变化不频繁,用户能容忍几秒的延迟
- 轮询间隔:5秒
- 用户体验可接受
邮箱新邮件检查:
- 邮件不是实时性很强的应用
- 轮询间隔:1-2分钟
- 完全够用
⏳ Long Polling(长轮询)
工作原理
客户端发请求后,服务器不立即响应,而是等待直到有新数据或超时
实现细节
服务器端伪代码:
特点分析
优势:
- 实时性好:有消息时几乎立即返回,延迟很低
- 资源效率高:比普通轮询减少了大量无效请求
- 实现相对简单:基于HTTP,比WebSocket简单
劣势:
- 服务器资源占用:每个客户端都要占用一个长连接
- 超时处理复杂:需要处理各种超时和重连情况
- 负载均衡困难:长连接让负载均衡变复杂
适用场景
聊天应用的消息接收:
- 需要较好的实时性
- 消息频率不是特别高
- 用户数量中等规模
订单状态更新:
- 用户下单后等待状态变化
- 需要及时通知状态变更
- 连接时间相对较短
🔌 WebSocket
工作原理
建立一个持久的双向通信连接,就像打通了一条专用电话线
通信模式
双向实时通信:
特点分析
优势:
- 真正实时:消息延迟极低,毫秒级
- 双向通信:服务器和客户端都能主动发送消息
- 协议开销小:建立连接后,每次通信的协议头很小
- 功能强大:支持文本和二进制数据
劣势:
- 实现复杂:需要处理连接管理、心跳、重连等
- 服务器压力大:每个连接都要保持状态
- 网络要求高:对网络稳定性要求较高
- 调试困难:比HTTP难调试和监控
适用场景
在线游戏:
- 需要极低延迟
- 双向实时交互
- 数据传输频繁
实时协作工具(如Google Docs):
- 多人同时编辑
- 需要实时同步所有用户的操作
- 交互非常频繁
📊 三种方案对比
实时性对比
服务器资源消耗
开发复杂度
🎯 选择决策
根据实时性需求选择
秒级延迟可接受:
- Polling:邮箱检查、股票价格、天气更新
- 轮询间隔:5-30秒
- 实现成本最低
准实时(1秒内):
- Long Polling:聊天应用、订单状态、通知系统
- 延迟:100-500毫秒
- 平衡实时性和复杂度
真实时(毫秒级):
- WebSocket:在线游戏、实时协作、直播弹幕
- 延迟:50-100毫秒
- 最佳用户体验
根据用户规模选择
小规模(<1000用户):
- 三种方案都可以,根据实时性需求选择
- 服务器资源不是瓶颈
中等规模(1000-10000用户):
- 避免高频Polling:会产生很大的QPS
- Long Polling较好:在实时性和资源之间平衡
- WebSocket需要优化:连接管理要做好
大规模(>10000用户):
- Polling要慎重:可能压垮服务器
- Long Polling需要集群:单机hold不住这么多长连接
- WebSocket需要专业方案:如使用专门的推送服务
根据业务特点选择
消息频率低,用户关注度不高:
- 选择Polling
- 例子:系统公告、版本更新通知
消息频率中等,用户比较关注:
- 选择Long Polling
- 例子:订单状态、支付结果、聊天消息
消息频率高,强交互性:
- 选择WebSocket
- 例子:在线游戏、实时编辑、直播互动
💼 实际项目中的组合使用
混合方案
很多实际项目会组合使用多种技术:
微信Web版的技术选型:
- 消息接收:Long Polling(实时性好,实现相对简单)
- 输入状态:WebSocket(需要实时显示"对方正在输入")
- 离线消息:Polling(用户上线时拉取离线消息)
在线协作文档:
- 文档编辑:WebSocket(实时同步编辑操作)
- 用户列表:Long Polling(显示当前在线用户)
- 版本历史:Polling(定期检查是否有新版本)
💡 核心总结
技术选择的本质:在实时性、复杂度、资源消耗之间找平衡
选择指南:
- 能容忍几秒延迟 → Polling
- 需要1秒内响应 → Long Polling
- 需要毫秒级实时 → WebSocket
所以一般chat sys都用的ws来通信

为什么选择kv store?
🎯 聊天系统的数据特点
聊天数据的核心特征
简单的键值关系:
- 消息ID → 消息内容
- 用户ID → 用户在线状态
- 会话ID → 最后一条消息
- 用户ID → 好友列表
访问模式:
- 读多写少:用户更多时间在看消息,发消息相对较少
- 简单查询:大部分是根据ID直接查找,很少复杂的关联查询
- 高并发:大量用户同时在线聊天
🔧 KV Store在聊天系统中的具体应用
1. 消息存储
2. 用户会话状态
3. 在线状态管理(Presence服务)
4. 消息历史索引
🚀 为什么选择KV Store而不是关系数据库?
性能优势
读取性能:
写入性能:
扩展性优势
水平扩展:
📊 具体的数据流
发送消息流程
加载聊天历史流程
🎨 与关系数据库的配合
混合架构设计
数据同步策略
⚡ 性能数据对比
响应时间
并发能力
🔍 KV Store的选型
Redis(内存型)
适用场景:
- 在线状态管理
- 最近消息缓存
- 会话状态缓存
特点:速度极快,但成本较高
Cassandra(磁盘型)
适用场景:
- 消息历史存储
- 大量历史数据
- 需要持久化的数据
特点:容量大,成本低,写入性能好
💡 总结
聊天系统使用KV Store的原因:
- 数据模式简单:主要是键值查询,很少复杂关联
- 性能要求高:用户期望消息秒到,延迟要极低
- 并发量大:大量用户同时在线聊天
- 扩展性需求:需要支持百万、千万用户规模
- 成本考虑:KV Store在大规模下成本更低
KV Store在聊天系统中的价值:
- 实时性:毫秒级的消息读写
- 可扩展性:简单的水平扩展
- 高可用:分布式架构天然高可用
- 成本效益:大规模下性价比更高
1 on 1 chat flow

message同步across多设备
🎯 cur_max_message_id的作用
核心概念
cur_max_message_id = 当前设备已同步到的最新消息ID
这个ID表示:
- 该设备已经接收并处理了ID小于等于这个值的所有消息
- 用于标记设备的"同步进度"
- 帮助服务器知道该给这个设备推送哪些消息
📱 多设备同步场景
典型使用场景
实际生活例子
微信多设备使用:
- 你在公司电脑上聊天到下午6点(消息ID到了842)
- 下班路上打开手机微信
- 手机发现自己只有到消息653的数据
- 手机向服务器请求:给我推送654-842之间的所有消息
- 手机快速"补齐"白天错过的消息
🔄 同步机制详解
1. 设备上线时的同步流程
2. 实时消息同步
3. 跨设备消息一致性
💾 存储设计
KV Store中的数据结构
消息存储与索引
⚡ 优化策略
1. 批量同步优化
2. 增量同步
3. 消息去重
🔧 实际实现细节
1. 消息ID的设计
2. 断线重连处理
3. 冲突处理
📊 性能考虑
1. 内存使用优化
2. 网络带宽优化
💡 核心价值
cur_max_message_id解决的核心问题:
- 多设备一致性:确保用户所有设备都有相同的消息历史
- 断线续传:设备重连后能精确恢复到断线前的状态
- 性能优化:只同步必要的消息,避免重复传输
- 消息完整性:保证消息不丢失、不重复、有序
设计精髓:
- 状态追踪:每个设备都知道自己同步到哪里了
- 增量同步:只传输缺失的部分,高效利用带宽
- 一致性保证:基于全局有序的消息ID确保一致性
- 容错能力:设备离线、网络中断都不影响最终一致性
Group chat

A sends msg in the group chat(samll group)
User Disconnection
🔌 用户断线的场景分类
1. 主动断线
用户主动操作:
- 关闭聊天应用
- 手机锁屏
- 切换到其他应用
- 主动登出
2. 被动断线
网络或系统问题:
- 网络信号不稳定(地铁、电梯)
- WiFi到移动网络切换
- 手机电量耗尽自动关机
- 应用被系统杀掉(内存不足)
- 服务器重启或故障
3. 网络分区
连接异常:
- 连接超时但没有显式关闭
- 防火墙阻断
- 代理服务器问题
- TCP连接僵死
🚨 断线检测机制
1. 心跳检测(Heartbeat)
2. WebSocket连接状态监控
3. TCP Keep-Alive
📊 断线后的状态更新
1. 在线状态变更
2. 设备同步状态保存
3. 连接会话清理
📬 消息处理策略
1. 离线消息缓存
2. Push通知触发
3. 消息送达确认
🔄 重连处理流程
1. 设备重连检测
2. 消息补偿机制
3. 连接稳定性优化
⚡ 性能优化考虑
1. 大量用户同时断线
2. 频繁断线用户
3. 内存和连接管理
💡 核心设计原则
用户断线处理的关键要点:
- 状态一致性:确保用户在线状态在所有地方都正确更新
- 消息完整性:断线不能导致消息丢失,重连后能完整同步
- 性能优化:大量断线不能影响系统整体性能
- 用户体验:断线重连对用户尽可能透明
最佳实践:
- 预防为主:通过心跳、重连策略减少断线影响
- 快速检测:及时发现断线,避免无效操作
- 优雅降级:网络不好时降低实时性要求,保证基本功能
- 数据驱动:通过监控数据优化断线处理策略
用户断线处理是聊天系统稳定性的核心,直接影响用户的使用体验!