消息推送系统方案
临时整理的一份方案,内容还需细化和推敲。
=========================================================
消息推送创建/发送
消息推送后台管理:
- 消息推送模块:
- 消息推送管理:
- 新建推送消息:
- 消息支持在指定的时间开发推送功能;
- 消息支持按照不同群体分类进行精准推送功能;
- 标签推送:给用户增加标签属性,根据标签进行分组推送;
- 多维度推送:用户性别、IP地址(一般定位到省、市)等;
- 沉默用户推送:特定推送内容,唤醒沉默用户,提高用户留存;
- 沉默用户 = 当前日期 - 用户最后心跳日期,跟设定值比较,校验用户是否为沉默用户;
- 升级版本推送:新版本发布,推送消息给老版本用户,提醒用户更新版本;
- 推送消息表字段:
- 推送ID
- 推送人
- 推送内容
- 推送图片URL
- 是否定时推送
- 推送时间:默认当前日期。定时任务,指定消息推送日期;
- 后续动作:打开应用、打开链接、打开指定页面
- 目标用户:标签推送、多维度推送、沉默用户推送、升级版本推送。
- 新建推送消息:
- 消息推送管理:
消息推送发送过程
- 思路:
- Server有发布新的消息,通过建立的长连接push 给Client;同时Client加大轮询间隔,按照设定间隔从Server /消息队列 pull一次数据,这样做的好处:①针对推送消息时不在线的Client 再次上线能够收取到离线消息;②预防Client 遗漏掉任何推送消息,保证接收到消息数据的时序。
- 步骤(Socket长连接Demo已实现):
- Client 向Server 发送请求,建立长连接,Server可以通过这个socket发送数据给Client;
- 在向Server发送请求时,需要增加Server连接认证机制,只有认证通过的请求才被允许建立长连接;
- 认证机制:可以使用用户的TokenID作为**,通过对TokenID的解析对比操作进行校验。
- 长连接信息表:存储每一条长连接信息,并记录其状态信息;
- 表字段:
- 长连接ID
- TokenID
- 最后心跳日期
- 连接状态:true/false
- Client 定时向Server发送心跳包,告知 Server 继续保持长连接;
- 心跳包:自定义心跳包,包含终端秘钥参数。
- Server根据接收到的心跳包时段间隔判断Client是否连接正常。
- 心跳机制:
- Client启动定时器,定期向Server发送特定心跳包;
- Server收到心跳包,保存获取时间,并回复一个响应包告知Client 长连接正常;
- Client如果在一定时间内没有收到回应,则长连接失效。
- Server为每个客户端启动超时定时器,在指定时间内没有收到Client发来的包,则使用 时间差策略 对该长连接进行检查长连接是否中止的操作:
- 时间差策略公式:多久没收到心跳时间 = 当前时间 - 最后一次更新时间,然后用 多久没收到心跳时间值 跟 设定值比较,校验长连接是否超时。
- 心跳机制:
- Client 向Server 发送请求,建立长连接,Server可以通过这个socket发送数据给Client;
- 推送消息状态:
- 移动终端在线:消息立即到达;
- 移动终端不在线:消息类型分为 按序消息 和 覆盖消息。
- 按序消息:每一条都保存,在移动终端上线后按照消息顺序由终端主动拉取;
- 覆盖消息:只保留最后一条消息,在移动终端上线后直接实时推送消息。
- 延伸出来的问题:
- 移动终端在线时,可以通过Socket 直接获取推送的消息,但是终端不在线时推送的消息,如何实现终端再次上线后及时获取到推送的消息?
- 方案1:存储到服务器表中,推送信息时将所有数据先存储到数据库中,然后根据推送到客户端后反馈的已到达状态删除那些已经到达的数据(这样做是为了能够统计“到达人数”),终端再次上线时主动向服务端发送请求,获取未到达状态下的所有消息;
- 方案2(已实现 Redis消息队列存取数据Demo):将未到达状态的消息放在消息队列中,等待终端再次上线时主动获取队列中存储的所有消息。
- 这里我的想法是因为项目中使用了Redis,那么可以将Redis当做一个消息队列用来存放未到达的消息(即离线消息),这样对于维护工作也会方便很多。
- 移动终端在线时,可以通过Socket 直接获取推送的消息,但是终端不在线时推送的消息,如何实现终端再次上线后及时获取到推送的消息?
消息推送指标统计
消息推送后台管理
- 推送指标管理:整理消息推送到移动终端后的反馈结果,为了更方便通过推送消息情况观察用户对产品的使用情况。
- 推送指标统计:
- 到达率:到达人数/发送数量
- 到达人数:移动终端接收到消息的数量总计;
- 发送数量:发布消息推送数量总计;
- 打开率:打开人数/到达人数
- 打开人数:点击推送跳转到相关页面的数量总计;
- 到达人数:移动终端接收到消息的数量总计;
- 卸载率:推送1小时候卸载人数/到达人数
- 卸载人数:判断卸载事件,使用卸载时间跟消息到达时间比较,统计1个小时内卸载操作的人数总计;
- 到达人数:移动终端接收到消息的数量总计;
- 留存率:接受push的留存率 = 2 * 未接收push的留存率
- 到达率:到达人数/发送数量
- 指标字段表:
- 推送消息ID
- TokenID
- 推送终端:Android、iOS
- 是否达到
- 是否打开
- 是否已卸载
- 点击率
- 推送指标统计:
推送消息类型实现
- 版本升级:
- 使用场景:
- 用户刚打开App时收到推送的版本升级信息;
- 用户点击“立即更新”:
- 跳转到应用市场对应产品页面,手动升级;
- 在通知栏生成下载更新条,自动下载新版本;
- 在应用内下载更新。
- 用户点击“立即更新”:
- 用户刚打开App时收到推送的版本升级信息;
- 使用场景:
- 实现思路:
- 移动终端每次打开后,主动向消息推送服务端抓取一次最近日期的版本升级类型的消息,然后将获取到的版本升级信息跟本地的版本号进行对比,高于本地版本号则执行版本更新提示操作,反之则不进行任何操作。
- 这里需要将安装包单独放在一个目录中,提供一个下载路径,在通知栏中下载的时候直接从这个路径中拉取apk文件即可。
- 移动终端每次打开后,主动向消息推送服务端抓取一次最近日期的版本升级类型的消息,然后将获取到的版本升级信息跟本地的版本号进行对比,高于本地版本号则执行版本更新提示操作,反之则不进行任何操作。
- 版本升级信息返回参数内容:
- 包含内容:版本号、图片Url、升级标题、升级内容、升级日期。
- 相关技术:
- Android 实现通知栏App 版本更新:
https://blog.****.net/qq_35070105/article/details/71908290
- 消息中心:
- 使用场景:
- 用于系统日志通知,例如:发货通知、物流信息、评论回复、动态更新等。
- 使用场景:
- 实现思路:
- 系统将信息推送给特定用户同时写入到消息信息表中,移动终端在获取到推送消息后将条数显示出来并提示用户有新消息;
- 首次打开该页面加载数据时,需要终端从消息队列中拉取一次数据,并且每隔一段时间就重新拉取一次,防止有遗漏的消息。
- 通知栏:
- 使用场景:
- 多用于各种新闻资讯、活动推送、系统通知等。
- 用户点击通知栏消息后,需打开该应用并且定位到指定内容页面中。
- 使用场景:
- 实现思路:
- 移动终端接收到服务端推送过来的新消息后,将消息内容通过通知栏的形式展示在锁屏界面上。
- 实现技术:
- Android 自定义通知栏:
https://blog.****.net/wangxiaohuhu1314/article/details/74474716
备注:
- 去重过滤:
- 要制定规则,保证一个用户每天最多收到 N 条push(N一般是2),并且要考虑系统优先级;
- 定义多类 push 优先级:
- 例如:一般系统功能类 > 营销活动类。
- 文案赛马机制:
- 若干条文案,先从用户中抽取10%作为实验用户,然后将文案平均下发到实验用户中,观察一段时间后,将点击率最高的文案推送给剩余90%的用户。