消息协议选择

IMPP

IMPP 即时信息和空间协议

特性:

  1. 这是一个协议标准,没有具体实现
  2. 其中涉及的角色具有参考意义,是非常通用的设计(e.g. “即时消息服务”、“状态服务”、“发送者”、“订阅者”、“观察者”、“收件箱”、“发件箱”)
  3. 草案:RFC2778 | RFC2779

取舍:

  1. 太过抽象,可读性差
  2. 仅是一个模型,和自研无差别

XMPP

XMPP 可扩展消息和表示协议

特性:

  1. 一种基于XML的应用层协议
  2. XML可以跨平台,跨IM服务传输
  3. 适用于一些邮箱应用,如Spark
  4. 开源地址

取舍:

  1. 文本性能差,信息冗余,压缩率低
  2. 解析dom极耗时,性能极差
  3. 难以保证消息可靠性Qos

SIMPLE

SIMPLE 针对即时通讯和空间平衡扩充的进程开始协议

特性:

  1. 应用于流媒体,音视频场景,这是对其的扩展
  2. 针对IM聊天场景的扩展,是应用层文本协议,类似HTTP
  3. sip协议相关
  4. 开源地址

取舍:

  1. 文本协议,压缩率低,占用网络带宽
  2. 无直接相关的SIMPLE,SIP/SDP都需要较大的改造成本
  3. 不满足性能和可迭代性
  4. 难以保证消息的可靠性Qos

MQTT

MQTT 消息队列遥测传输即时通讯协议

特性:

  1. 异步通信,消息报文简单,适合推送场景
  2. 轻量级发布订阅模式,一对多的分发模式,资源消耗也很少
  3. 代码少,可以在多种单片机上轻松实现
  4. 支持Qos(0~2)
  5. 适用于设备的存储和网络带宽有限的物联网场景
  6. 预定义为弱网环境,所以传输效率较高,消息可达性较高
  7. 参考资料
    MQTT格式
    取舍:
  8. 需要增加一些可变头,才能支持时序性
  9. 基于IM需求定制化开发的场景很多,扩展性较差
  10. 协议本身是为物联网设计,不是专门定制

为什么MQTT适合推送场景:

  1. 异步通信模型:MQTT是采用异步通信模型,消息的发送者和接受者之间解藕,发送者无需等待订阅者的回复,这使得MQTT在推送场景中表现出色。
  2. 发布/订阅模式:发布者将消息发布到特定的主题,而订阅者则通过订阅感兴趣的主题来接受消息。这使得消息的推送非常灵活,允许多个订阅者接受来自同一主题的消息,从而实现广播和多播的场景
  3. 持久性连接:MQTT支持客户端与服务端之间的持久连接,客户端可以保持长期连接,即时在网络断开后,连接恢复时也能收到之前未接受到的消息,这个特性对于推送场景中的设备状态监控,实时通知等应用非常有用
  4. 轻量级和低带宽消耗:MQTT协议本身非常轻量级,消息头部相对较小,协议开销小,适合在有限的带宽中工作,这使得MQTT在推送大量消息的场景中能够有效的利用带宽
  5. Qos等级支持:MQTT支持不同的消息传输质量等级Qos,保证消息的可靠性,能够确定消息推送到接受者

websocket

WebSocket 是一种网络通信协议,很多高级功能都需要它。

特性:

  1. 客户端和服务端仅一次握手就可以创建连接
  2. 使用简单,支持全双工,各大浏览器均支持,多用于H5
  3. 复用HTTP通道,在HTTP基础上进行协议升级
  4. 基于数据帧格式进行传输
    格式
  5. 源码地址
  6. 性能压测对比
  7. 协议格式

取舍:

  1. 需要业务自己保证消息时序性
  2. 需要业务处理断线重连等场景,扩展性弱
  3. 建立长连接时,需要通过HTTP协议升级,建立和重连都很慢
  4. 数据帧格式定制化能力较差,信息有冗余
  5. 原生客户端难以扩展,协议库需要二次开发
  6. websocket的协议还是字符流协议,信息压缩率差,浪费带宽

自研二进制协议

特性:

  1. 几乎主流IM APP公司都会这么做
  2. 灵活/高效/难以破解

取舍:

  1. 通用性差
  2. 需要手写字节流处理逻辑,容易出错,迭代效率低

私有协议+开源序列化

特性:

  1. 客服了自研二进制协议的通用性和维护性的问题
  2. Protobuf
  3. Protobuf通信协议详解

取舍

  1. 比较perfect了
  2. 就自己用

protobuf的不足:

  • Protbuf 与 XML 相比也有不足之处。它功能简单,无法用来表示复杂的概念。
  • XML 已经成为多种行业标准的编写工具,Protobuf 只是 Google 公司内部使用的工具,在通用性上还差很多。
  • 由于文本并不适合用来描述数据结构,所以 Protobuf 也不适合用来对基于文本的标记文档(如 HTML)建模。
  • 另外,由于 XML 具有某种程度上的自解释性,它可以被人直接读取编辑,在这一点上 Protobuf 不行,它以二进制的方式存储,除非你有 .proto 定义,否则你没法直接读出 Protobuf 的任何内容