原文: http://ceit.uq.edu.au/content/how-xmpp-works-step-step
作者: Yilun Fan, 日期 2011-01-05 13:09
XMPP 核心协议 http://xmpp.org/rfcs/rfc3920.html
XMPP 要点.
<stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>
<stream:features> <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'> <required/> </starttls> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>DIGEST-MD5</mechanism> <mechanism>PLAIN</mechanism> <mechanism>EXTERNAL</mechanism> </mechanisms> </stream:features>
Client: 客户端发送 STARTTLS 到服务器.
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
Server: 服务器返回消息显示 TLS 已被允许:
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
<failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> </stream:stream>
在失败的情况下, 服务器会关闭 TCP 连接.
Client: 如果 TLS 已被服务器正确处理, 客户端发送请求一个新的 session:
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>
Server: 服务器响应一个 XML stream, 指示是否需要 SASL 交涉.
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'> <stream:features> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>DIGEST-MD5</mechanism> <mechanism>PLAIN</mechanism> <mechanism>EXTERNAL</mechanism> </mechanisms> </stream:features>
“\0UserName\0Password”.
例如我想以用户名为“[email protected]”登录, 密码是“mirror”. 那么, 在进行base64编码之前, 用户名和密码按照上面的格式组织为一个新的字符串,“\0mbed\0mirror”, 再进行base64编码, 得到字符串“AG1iZWQAbWlycm9y”.
<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AG1iZWQAbWlycm9y</auth>
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>或者:
<failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
<iq type='set' id='bind_1'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/> </iq>
<iq type='set' id='bind_2'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <resource>someresource</resource> </bind> </iq>
<iq type='result' id='bind_2'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <jid>[email protected]/someresource</jid> </bind> </iq>
<iq to='example.com' type='set' id='sess_1'> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> </iq>Server: 服务器发回一个<iq> 片段表明 session 是否成功创建.
<iq from='example.com' type='result' id='sess_1'/>
<iq from='example.com' type='error' id='sess_1'> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> <error type='auth'> <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </iq>
如果以上步骤均成功完成, 那么客户端就可以发送 XMPP 片段到服务器和接收 XML stream了.
客户端可以发送 <iq> 片段来向服务器请求 roster 或者其他信息. 并可以使用 <presence> 片段来改变客户端的 presence 状态(比如在线, 离开等)
即时消息和其他的负载可以通过发送 <message> 片段来完成.
最后, 如果客户端想要结束聊天和关闭 XMPP session, 客户端需要发送一个关闭 stream的片段到服务器.
<presence type='unavailable'/> </stream:stream>
然后, 服务器将会改变客户端的 presence 状态为 “Offline” , 并且关闭 和客户端的 TCP 连接.
(完)