IM协议设计

IM协议设计

在实际开发中,为了及时的通知APP端一些事情,我们会借助第三方平台,进行推送。今天,我们来分析一下推送系统协议。

推送系统遇到的问题

在设计协议之前,我们考虑一些实际的问题:

  1. APP没有一个固定的网络地址,只能通过主动连接服务器,建立TCP长链接,来进行推送。

  2. 移动环境下,APP断网是非常普遍的,即推送任务会失败

  3. 在大并发的情况下,服务器宕机也是非常有可能的。

  4. APP可能不会随时连上服务器,而服务器需要保存一些非常重要的消息,等待APP连接上,推送给APP

  5. 移动环境下,节省流量也是非常重要的,毕竟不是人人都有4G

  6. 网络安全问题,日益严重,我们需要安全的推送

  7. 协议的兼容性

  8. 由于GSM网关,所以需要发送心跳包,避免NET转换被剔除

如何解决

可以发现,一个好的推送协议设计,还是非常困难的。总结下来,我们遇到的问题大致如下:

  1. 节约流量:采用protobuf这种二进制协议进行推送,但是也可以考虑JSON + UTF-8的方式

  2. 推送失败处理:无论服务器还是APP,都采用日志先行的策略,如果发送失败,则进行RETRY,直到到达推送极限次数后,报告错误。

  3. 安全性:采用SSL/TLS连接,基本上能解决安全链接的问题,如果条件比较拮据,可以把证书放在APP端。

  4. 协议兼容:可以参考APP兼容性设计中的协议兼容部分。

  5. 心跳包:一般来说,因为移动网络和互联网之间存在一个NET网关,它的有效时间为6分钟左右,所以APP端需要定时的发送心跳包到服务器,一般间隔时间为3-5分钟。同时,通过心跳包,服务器可以发现已经死掉的链接,及时的释放资源。

RETRY机制

在上述问题中,其他问题都比较好解决,但是消息重发机制,还是比较难以实现的。 这几介绍一下RETRY机制的设计:

  1. 加入UUID作为该消息的唯一ID,且在服务器端保留最后的100条该用户的消息,当APP端把消息推送到服务器的时候,服务器先去重,避免接受到相同的消息进行推送。

  2. 当APP连接上网络后,首先检测待发送的消息列表中是否为空,如果不为空,则根据FIFO来提取待发送的消息。直到服务器返回OK后,才把本条消息从待发送队列中删除。

  3. 发送失败的延迟推送算法,建议采用TCP的重发时间机制,也就是指数退避算法。

协议具体设计

这里使用JSON描述

{
	MODULE:PUSH
	VERSION:1 //版本号
	ID: UUID  //消息UUID
	TYPE: GROUP | PRIVATE | SYSTEM //消息会话类型
	TARGET_ID: STRING  //消息要发送到的目标ID,如果是GROUP,则是群的ID
	TIME:LONG //消息发送时间
	USER_ID : STRING //发送该该消息的用户ID
	CONTENT:{
		TYPE : STRING -> TEXT | IMAGE //消息的内容类型
		[DATA]: STRING -> BASE64_IMAGE | TEXT //消息的具体内容,可选
	}
}

一些实际问题

粘包

在使用TCP的过程中,会遇到粘包的问题,其根本原因是TCP是面向流链接的,所以,在传输一消息的时候,需要在开始处添加 该消息的长度 , 建议采用 [TCP长度,固定4byte + TCP报文]的格式。

消息有序性

在推送消息的时候,我们需要考虑消息的有序性。所以,在APP推送到服务器,或者服务器推送到APP端的时候,需要按序推送,只有前一条消息推送成功后,才能推送后一条。

总结

可以发现IM协议的设计和TCP协议是非常类似的,额外的添加了消息持久化的功能。对于消息有序性这个问题,引发的同一时间只有一条消息发送这个问题,可以考虑TCP的滑动窗口机制。

参考

Netty系列之Netty百万级推送服务设计要点

微信、陌陌等著名IM软件设计架构详解

转载于:https://my.oschina.net/darkgem/blog/620621

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值