通过ejabberd的日志,整理了下客户端登录流程。
1. 通过TCP连接5222端口的流程:
(1) 客户端向服务器发送stream流
<stream:stream to="nba.com" xml:lang="*" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">(2) 服务器应答stream
<?xml version='1.0'?> <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='4171758611' from='nba.com' version='1.0' xml:lang='en'>(3) 服务器发送流特性
<stream:features> <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>PLAIN</mechanism> </mechanisms> <c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/> <register xmlns='http://jabber.org/features/iq-register'/> </stream:features>(4) 客户端发送tls请求
<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>(5) 服务器回应并开始TLS握手
<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>(6) TLS握手完成后,客户端重新初始化stream流
<stream:stream to="nba.com" xml:lang="*" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">(7) 服务器应答
<?xml version='1.0'?> <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='703708799' from='nba.com' version='1.0' xml:lang='en'>(8) 服务器告知客户端支持的SASL验证机制
<stream:features> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>PLAIN</mechanism> </mechanisms> <c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/> <register xmlns='http://jabber.org/features/iq-register'/> </stream:features>(9) 客户端选择简单认证机制并发送用户名密码
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN"> AGNoZW53ZW5jYW4ja2VkYWNvbS5jb20AMjEyMThjY2E3NwgzNGQyYmExOTIyYzMzZTAxNTExMDU= </auth>(10) 服务器告诉客户端校验通过,SASL握手完成
<success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>(11) 客户端再次初始化stream流
<stream:stream to="nba.com" xml:lang="*" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" xmlns="jabber:client">
(12) 服务器应答
<?xml version='1.0'?> <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='2767342509' from='nba.com' version='1.0' xml:lang='en'>
(13) 通知客户端进行资源绑定
<stream:features> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> <c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/> <register xmlns='http://jabber.org/features/iq-register'/> </stream:features>
(14) 客户端请求资源绑定
<iq type="set" id="0"> <bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"> <resource>boston</resource> </bind> </iq>
(15) 服务器应答
<iq id='0' type='result'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <jid>[email protected]/boston</jid> </bind> </iq>
(16) 客户端请求session绑定
<iq type="set" id="1"> <session xmlns="urn:ietf:params:xml:ns:xmpp-session"/> </iq>
(17) 服务器应答
<iq type='result' id='1'> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> </iq>至此,可认为登陆完成,后续进行能力协商,发送其他请求消息,发送出息消息等。
2. 通过http连接5280端口的流程
http方式的交互是通过BOSH协议完成的,详细可参见
http://xmpp.org/extensions/xep-0124.html
http://xmpp.org/xmpp-protocols/xmpp-extensions/
具体流程为:
(1) 发起bosh会话
<body rid='16488487' xmlns='http://jabber.org/protocol/httpbind' to='nba.com' xml:lang='en' wait='60' hold='1' content='text/xml;charset=utf-8' ver='1.6' xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'/>
(2) 服务器应答
<body xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486' wait='60' requests='2' inactivity='30' maxpause='120' polling='2' ver='1.8' from='nba.com' secure='true' authid='1145683568' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' xmpp:version='1.0'> <stream:features xmlns:stream='http://etherx.jabber.org/streams'> <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'> <mechanism>PLAIN</mechanism> </mechanisms> <c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/> <register xmlns='http://jabber.org/features/iq-register'/> </stream:features> </body>
(3) 客户端发送用户名密码
<body rid='16488488' xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486'> <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'> AGNoZW53ZW5jYW4ja2VkYWNvbS5jb20AMjEyMThjY2E3NwgzNGQyYmExOTIyYzMzZTAxNTExMDU= </auth> </body>
(4) 服务器响应告知校验结果
<body xmlns='http://jabber.org/protocol/httpbind'> <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/> </body>
(5) 客户端重新初始化stream流
<body rid='16488489' xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486' to='nba.com' xml:lang='en' xmpp:restart='true' xmlns:xmpp='urn:xmpp:xbosh'/>
(6) 服务器通知完成资源绑定
<body xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486' wait='60' requests='2' inactivity='30' maxpause='120' polling='2' ver='1.8' from='nba.com' secure='true' authid='3855745118' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' xmpp:version='1.0'> <stream:features xmlns:stream='http://etherx.jabber.org/streams'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> <c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='AxFG3uvIZfHAbBjOUb9t3klmoos='/> <register xmlns='http://jabber.org/features/iq-register'/> </stream:features> </body>
(7) 客户端请求资源绑定
<body rid='16488490' xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486'> <iq type='set' id='_bind_auth_2' xmlns='jabber:client'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <resource>boston</resource> </bind> </iq> </body>
(8) 服务器应答
<body xmlns='http://jabber.org/protocol/httpbind'> <iq xmlns='jabber:client' id='_bind_auth_2' type='result'> <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'> <jid>[email protected]/boston</jid> </bind> </iq> </body>
(9) 客户端请求session绑定
<body rid='16488491' xmlns='http://jabber.org/protocol/httpbind' sid='90582e464361adb537351e65ecfa66d1336ea486'> <iq type='set' id='_session_auth_2' xmlns='jabber:client'> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> </iq> </body>
(10) 服务器应答
<body xmlns='http://jabber.org/protocol/httpbind'> <iq xmlns='jabber:client' id='_session_auth_2' type='result'> <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/> </iq> </body>