推送总览
远程推送解决的是“应用不在前台、长连接已断开时,如何让用户知道有新消息”。融云通过客户端集成厂商推送 SDK、服务端选择通道投递来实现;本项目目前只实现了服务端离线消息 webhook,通道与客户端能力尚未实现。
当前能力边界(必须如实告知)
本项目没有 APNs、FCM 或国内厂商的发送实现,没有通知点击跳转与角标。
已实现:设备 token 台账(客户端 REST 注册/查询/注销,幂等 + 每用户 20 个上限)、6 个厂商通道的配置存储与校验、投递尝试记录(no_token / not_configured,sent 恒 0)与手动重试。
另有服务端“离线消息 webhook”与 push.send:接收者无在线连接时 POST 应用配置的 URL,3 秒超时、无签名/重试。
完整状态机与新接口见 推送通道与投递;本页保留为链路背景。
离线推送链路
标准链路是:客户端取得 token → 上报服务端 → 服务端在用户离线时组装通知 → 通过 APNs/FCM/厂商通道投递 → 系统通知栏展示 → 用户点击进入会话。本项目的实现停在“服务端组装并 POST webhook”。
| 环节 | 融云做法 | 本项目当前 | 状态 |
|---|---|---|---|
| 1. 客户端获取 token | 集成厂商推送 SDK 后取得 token / deviceToken,并由 SDK 上报 | 由宿主 App 集成厂商 SDK 后自行取得;服务端不代取 | ✅ 业务侧完成 |
| 2. 服务端登记设备 | 按用户与设备保存 token、平台、包名、语言 | 客户端 REST POST /api/apps/{appkey}/push/tokens(幂等、每用户 20 个活跃 token) | 🟡 台账已实现;SDK 方法未实现 |
| 3. 触发推送 | 用户离线且消息可推送时,按应用配置选通道 | 离线消息 webhook + push.send;Admin 投递尝试记录(no_token/not_configured) | 🟡 部分实现(无厂商发送) |
| 4. 通道投递 | APNs / FCM / 小米 / 华为 / 荣耀 / OPPO / vivo / 魅族 / RongPush | 6 个通道仅配置存储/校验/脱敏;deliveryImplemented=false | ⛔ 未实现 |
| 5. 系统通知展示 | 厂商通道或 SDK 本地通知 | 无;本项目不发系统通知 | ⛔ 未实现 |
| 6. 点击跳转 | SDK 发出 Intent / 回调,默认进会话 | 无;投递记录不含点击事件 | ⛔ 规划中 |
| 7. 角标 | 按会话未读累加或厂商角标接口 | 无角标能力;只有会话 unreadCount | ⛔ 规划中 |
本项目已实现的部分
离线消息 webhook
- 触发条件:消息投递时,接收者没有任何在线 WS 会话(发送者本人的其他端不计入接收者)。
- 投递方式:服务端异步
POST应用配置的webhookUrl,content-type: application/json,3 秒超时;失败只写日志,不影响消息投递。 - 载荷:
{ appkey, userId, reason: "offline", message },message是完整消息对象(含content)。 - 配置:Admin API
POST /api/admin/apps/{appkey}/push,字段webhookUrl、enabled;URL 必须是 http(s)。 - 限制:无签名、无重试、无幂等键、无死信;webhook 接收方需要自行去重与补偿。
不落地通知(push.send)
服务端 push.send 支持 scope=all|tag|package|user|users,把标题、内容、extras 与目标数量投递到同一个 webhook,并记录推送日志与统计。它不是厂商通道:如果应用没有配置 webhook,投递数为 0。
设备 token 台账(已实现)
客户端用 Bearer 用户 token 调 POST /api/apps/{appkey}/push/tokens 注册厂商 token(幂等、每用户 20 个活跃上限、设备换绑自动停用旧记录);管理端可查/注销。它只是台账,不代表厂商通道可用。详见 推送通道与投递。
推送日志、统计与备注
| 能力 | 接口 | 说明 |
|---|---|---|
| 推送日志 | push.log.list | 按 pushId 或分页查询每次推送的投递结果 |
| 按天统计 | push.stats.day | 按日期聚合推送数量与投递结果 |
| 单次统计 | push.stats.by-id | 按 pushId 查询单次推送结果 |
| 推送备注名 | push.remark.set/get/remove | 用户级/群级推送备注名 |
| 用户免打扰时段 | user.push.period.set/get/remove | 保存/查询时段配置;当前未在 webhook 派发时生效 |
未实现的部分
| 能力 | 状态 | 说明 |
|---|---|---|
| 客户端厂商 token 获取 | ✅ 业务侧完成 | 宿主 App 集成厂商 SDK 后取得,服务端不代取 |
| 设备 token 台账 | ✅ 已实现 | 客户端 REST + 管理端;不代表厂商 token 仍有效 |
| 按设备推送 | ⛔ 未实现 | 投递只按 userId 选最近活跃 token,未真正发送 |
| APNs / FCM / 华为 / 小米 / OPPO / vivo 发送 | ⛔ 未实现 | 通道配置仅存储;适配器恒为 not_configured |
| 通知点击跳转 / 角标 / 分组 | ⛔ 未实现 | 投递记录没有点击事件,无角标接口 |
| 多语言推送模板 | ⛔ 未实现 | title/body 原样传入 |
| RongPush 自建通道 | ⛔ 未纳入 | 不在本项目范围 |
与融云的差异
| 项 | 融云 | 本项目 |
|---|---|---|
| 通道 | 多厂商 + RongPush | 6 个厂商配置可存;发送未实现,离线仅 webhook |
| 触发范围 | 单聊/群聊/系统/超级群(聊天室不支持) | 普通消息(含群聊/超级群),系统通知不触发 |
| 设备维度 | 按最后登录设备推送,可配置 Web/PC 在线时是否推手机 | 有 token 台账;投递只按 userId 选最近活跃 token |
| 推送内容 | 预置标题/内容、@ 文案优先、模板多语言 | 原样携带 message 或调用方 title/body |
| 可靠性 | 厂商通道重试与统计 | webhook fire-and-forget;投递记录可手动 retry,sent 恒 0 |
| 测试工具 | 控制台推送测试、模拟器验证 | 通道测试返回 implemented=false;只能验证 webhook |
继续阅读
- 推送通道与投递:token 注册、6 个通道配置、no_token/not_configured 状态机与重试
- 推送接入:webhook 配置、接收端示例与测试方法
- 消息计数、存储与推送策略
- 发送推送通知(push.send)
- 推送模块