这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
多端同步 - 用户有多个设备怎么办
一个用户,多个设备
入职第四周,老王给我看了一条用户投诉:
“我在手机上看了通知,标记已读,但在电脑上还是显示未读。这是 bug 吗?”
我打开数据库,查看这个用户的设备:
数据设计要点
- 查询目标是快速定位状态、任务或资源,避免在关键路径上做大范围扫描。
id user_id device_token platform brand last_active
1 123 abc123 ios iphone 2026-04-01 09:00
2 123 def456 ios ipad 2026-04-01 08:30
3 123 ghi789 android pixel 2026-04-01 07:00
这个用户有 3 台设备:iPhone、iPad、安卓手机。
当他在 iPhone 上标记已读,iPad 和安卓手机上的未读状态没有更新。
问题分析
我画了一个时间线:
时间 09:00 时间 09:05
iPhone: 用户标记已读 iPhone: 已读 ✓
iPad: 未读 ✗(状态没更新)
安卓: 未读 ✗(状态没更新)
核心问题:设备之间的状态没有同步。
同步方案
我调研了几个方案:
方案 A:轮询同步
App 定期向服务器查询最新状态:
每 30 秒:
App -> 服务器: 我的未读数是多少?
服务器 -> App: 你有 3 条未读
App: 更新显示
优点:实现简单 缺点:
- 延迟高(最长 30 秒)
- 浪费资源(即使没有更新也要查询)
方案 B:推送同步
当状态变化时,服务器主动推送:
iPhone: 标记已读
服务器: 收到,已读数减少 1
服务器 -> iPad: 推送同步消息(未读数:2)
服务器 -> 安卓: 推送同步消息(未读数:2)
iPad: 更新显示
安卓: 更新显示
优点:实时同步,资源高效 缺点:需要推送通道,App 需要监听推送
方案 C:长连接同步
App 与服务器建立 WebSocket 长连接:
iPad: 建立 WebSocket 连接
安卓: 建立 WebSocket 连接
iPhone: 标记已读(通过 WebSocket 发送)
服务器: 收到,广播给其他设备
服务器 -> iPad(WebSocket): 未读数:2
服务器 -> 安卓(WebSocket): 未读数:2
优点:实时、可靠 缺点:
- 需要维护长连接
- App 在后台时可能断开
- 实现复杂
我选择了方案 B(推送同步),因为:
- 我们已经有推送通道
- 实时性好
- 实现相对简单
推送同步实现
我设计了一个同步推送机制:
1. 定义同步消息类型
推送消息有两种:
- 用户通知:评论、点赞等业务通知
- 同步通知:状态同步消息(不显示给用户)
iOS 静默推送:
配置要点
- 配置表达的是环境差异和运行参数,不是业务规则本身。
content-available: 1 表示这是静默推送,iOS 会唤醒 App(最多 30 秒),但不显示通知。
安卓数据消息:
配置要点
- 配置表达的是环境差异和运行参数,不是业务规则本身。
没有 notification 字段,所以不会显示通知,App 需要在后台处理。
2. App 端处理同步消息
iOS 端:
安卓端:
3. 同步时机
什么时候触发同步?
其他触发同步的时机:
- 创建新消息
- 全部标记已读
- 删除消息
同步失败处理
如果同步推送失败怎么办?
我设计了一个降级方案:
当 App 打开时,主动查询同步状态:
消息删除同步
用户在一台设备上删除消息,其他设备也要删除。
App 端处理删除同步:
实时消息同步
用户正在 App 内查看消息中心,其他设备发送消息,怎么实时显示?
我使用了 WebSocket:
前端(App 内):
设备管理
用户可能更换设备,我们需要管理:
设备注册
设备清理
定期清理不活跃的设备:
小结
这周我学到:
- 多端同步问题:用户有多个设备,状态需要实时同步
- 同步方案:推送同步(iOS 静默推送、安卓数据消息)
- 降级处理:推送失败时,等待 App 打开时主动同步
- 实时更新:使用 WebSocket 实现消息中心实时更新
- 设备管理:注册、更新、清理设备
多端同步是通知系统的重要功能,让用户在不同设备上有一致的体验。
