消息协议选择
IMPP
IMPP 即时信息和空间协议
特性:
- 这是一个协议标准,没有具体实现
- 其中涉及的角色具有参考意义,是非常通用的设计(e.g. “即时消息服务”、“状态服务”、“发送者”、“订阅者”、“观察者”、“收件箱”、“发件箱”)
- 草案:RFC2778 | RFC2779
取舍:
- 太过抽象,可读性差
- 仅是一个模型,和自研无差别
XMPP
XMPP 可扩展消息和表示协议
特性:
- 一种基于XML的应用层协议
- XML可以跨平台,跨IM服务传输
- 适用于一些邮箱应用,如Spark
- 开源地址
取舍:
- 文本性能差,信息冗余,压缩率低
- 解析dom极耗时,性能极差
- 难以保证消息可靠性Qos
SIMPLE
SIMPLE 针对即时通讯和空间平衡扩充的进程开始协议
特性:
取舍:
- 文本协议,压缩率低,占用网络带宽
- 无直接相关的SIMPLE,SIP/SDP都需要较大的改造成本
- 不满足性能和可迭代性
- 难以保证消息的可靠性Qos
MQTT
MQTT 消息队列遥测传输即时通讯协议
特性:
- 异步通信,消息报文简单,适合推送场景
- 轻量级发布订阅模式,一对多的分发模式,资源消耗也很少
- 代码少,可以在多种单片机上轻松实现
- 支持Qos(0~2)
- 适用于设备的存储和网络带宽有限的物联网场景
- 预定义为弱网环境,所以传输效率较高,消息可达性较高
- 参考资料
取舍:- 需要增加一些可变头,才能支持时序性
- 基于IM需求定制化开发的场景很多,扩展性较差
- 协议本身是为物联网设计,不是专门定制
为什么MQTT适合推送场景:
- 异步通信模型:MQTT是采用异步通信模型,消息的发送者和接受者之间解藕,发送者无需等待订阅者的回复,这使得MQTT在推送场景中表现出色。
- 发布/订阅模式:发布者将消息发布到特定的主题,而订阅者则通过订阅感兴趣的主题来接受消息。这使得消息的推送非常灵活,允许多个订阅者接受来自同一主题的消息,从而实现广播和多播的场景
- 持久性连接:MQTT支持客户端与服务端之间的持久连接,客户端可以保持长期连接,即时在网络断开后,连接恢复时也能收到之前未接受到的消息,这个特性对于推送场景中的设备状态监控,实时通知等应用非常有用
- 轻量级和低带宽消耗:MQTT协议本身非常轻量级,消息头部相对较小,协议开销小,适合在有限的带宽中工作,这使得MQTT在推送大量消息的场景中能够有效的利用带宽
- Qos等级支持:MQTT支持不同的消息传输质量等级Qos,保证消息的可靠性,能够确定消息推送到接受者
websocket
WebSocket 是一种网络通信协议,很多高级功能都需要它。
特性:
取舍:
- 需要业务自己保证消息时序性
- 需要业务处理断线重连等场景,扩展性弱
- 建立长连接时,需要通过HTTP协议升级,建立和重连都很慢
- 数据帧格式定制化能力较差,信息有冗余
- 原生客户端难以扩展,协议库需要二次开发
- websocket的协议还是字符流协议,信息压缩率差,浪费带宽
自研二进制协议
特性:
- 几乎主流IM APP公司都会这么做
- 灵活/高效/难以破解
取舍:
- 通用性差
- 需要手写字节流处理逻辑,容易出错,迭代效率低
私有协议+开源序列化
特性:
- 客服了自研二进制协议的通用性和维护性的问题
- Protobuf
- Protobuf通信协议详解
取舍
- 比较perfect了
- 就自己用
protobuf的不足:
- Protbuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。
- XML 已经成为多种行业标准的编写工具,Protobuf 只是 Google 公司内部使用的工具,在通用性上还差很多。
- 由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。
- 另外,由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容