概述
XMPP(可扩展的消息传递和存在协议)当年是专门为即时消息应用设计的协议。
XMPP 历史稍长,比较成熟,应用和库也比较多,比如Jabber, Google Talk(现在改为 Hangouts 环聊),WhatsApp。 但是所使用的 XML 也比较繁琐, 消息体比较大, 所以在移动网络和物联网中有些力不从心。
MQTT(MQ Telemetry Transport)专门为 IoT 物联网的设备所设计的一种通信协议,适用于功率, 容量和计算能力比较低的设备。 它快速和可靠,消息体小,传输和解析效率比较高。比如 Facebook Messenger 就使用 MQTT。
对于在线聊天,在线会议领域,使用 WebSocket + JSON 也许是更加方便的选择,如果考虑到传输带宽的限制, WebSocket + ProtoBuffer 也许更好。
回顾 XMPP
XMPP 即 eXtensible Messaging and Presence Protocol 扩展消息和出席协议
它是以一种双向的流式XML表示的即时消息应用协议
大家最熟悉的即时消息应用莫过于 QQ 和微信了, 腾讯使用的是自己的私有协议, 而 XMPP 是开放的公有协议, 任何人都可以参考和免费使用
XMPP 有两个主要的协议
- XMPP Core - RFC6120 XMPP 核心协议
- XMPP Instant Messaging and Presence - RFC6121 XMPP 即时消息和出席协议
还有许多扩展的协议(http://xmpp.org/extensions), 常用的有
- XEP-0030 (PDF) Service Discovery
- XEP-0020 (PDF) Feature Negotiation
- XEP-0060 (PDF) Publish-Subscribe
- XEP-0047 (PDF) In-Band Bytestreams
- XEP-0004 (PDF) Data Forms
- XEP-0166 (PDF) Jingle
术语
- bare JID : 基本JID
localpart@domainpart - full JID: 完整 JID, 区别是加上了资源部分
localpart@domainpart/resourcepart - XML stanza: XML 节, 即一个XMPP的XML 消息
- route: 路由, 一个消息经由什么路径发到目的地
XMPP stream 搭建过程
participant client as client
participant server as server
client->server: 1) start stream
server-->client: 2) start stream and features
client->server: 3) auth
server-->client: 4) success
note over client, server: sasl negotiation success
client->server: 5) restart stream
server-->client: 6) restart stream and features
client->server: 7) resource bind iq
server-->client: 8) iq result
participant client as client
participant server as server
client->server: 1) start stream
server-->client: 2) start stream and features
client->server: 3) starttls
server-->client: 4) proceed
note over client, server: tls negotiation success
client->server: 5) restart stream
server-->client: 6) restart stream and features
client->server: 7) auth
server-->client: 8) challenge
client->server: 9) response
server-->client: 10) success
note over client, server: sasl negotiation success
client->server: 11) restart stream
server-->client: 12) restart stream and features
client->server: 13) resource bind iq
server-->client: 14) iq result
client->server: 15) session iq
server-->client: 16) iq result
架构
- 使用全局统一的地址 Global addresses
- 使用在线状态 Presence
- 使用可持久化的流 Persistent Streams
- 结构化的数据 Structured Data
- 使用客户机和服务器的分布式网络 Distributed Network of Clients and Servers
XML stanza
XMPP 消息流由三种类型的 Stanza 构成
|--------------------|
| <stream> |
|--------------------|
| <presence> |
| <show/> |
| </presence> |
|--------------------|
| <message to='foo'> |
| <body/> |
| </message> |
|--------------------|
| <iq to='bar'> |
| <query/> |
| </iq> |
|--------------------|
| ... |
|--------------------|
| </stream> |
|--------------------|
</pre>
XML 节
<message/>
<presence/>
<iq/>
例如
1. Presence 出席状态
<Presence
from="alice@aaa.com"
id="1232312312312"
to="bob@bbb.com"
>
<show>online</show>
</Presence>
2. Message 消息
<message
from="alice@aaa.com"
id="1232312312312"
to="bob@bbb.com"
type="chat"
>
<body>Hi Bob</body>
</message>
3. iq 请求与应答
- IQ request
<iq id="1952c42c-8fbf-43d6-9b85-5b0e79c3e3f7:sendIQ" to="bob@bbb.com" type="get" xmlns="jabber:client">
<vCard xmlns="vcard-temp"/>
</iq>
- iq response
<iq type="result" id="1952c42c-8fbf-43d6-9b85-5b0e79c3e3f7:sendIQ" from="bob@bbb.com" to="alice@aaa.com/converse.js-132196857" xmlns="jabber:client">
<vCard xmlns="vcard-temp">
<FN>Bob</FN>
<NICKNAME>boy</NICKNAME>
<URL/>
<ROLE>Dev</ROLE>
<EMAIL>
<INTERNET/><PREF/><USERID>bob@gmail.com</USERID
</EMAIL>
<PHOTO>
<TYPE>image/png</TYPE>
<BINVAL>iVBORw0KGgoAAAANSUhEU</BINVAL>
</PHOTO>
</vCard>
</iq>
从上面的协议快速回顾看出来, XMPP 协议和它用的 XML 有太多冗余信息,信息全则全矣,不够精简。近年来 Googgle Hangout, Microsoft Skype, Cisco Webex 都逐渐不再或减少了对 XMPP 的使用。
我曾经想过基于 XMPP , 把它从 XML 改造成 JSON 格式, 不过没找到动力和时间干这事。
我仍然坚信,世界需要一下类似 XMPP 这样的协议将各种 Instant Message 协议格式统一起来,让各种 Instant Message 工具互边互通, 让 WhatsApp, Line , QQ,Skype 都能相互进行消息通信