zoukankan      html  css  js  c++  java
  • XMPP 协议工作流程具体解释

      

    XMPP 要点.

    • 1. client(C) 和server端(S) 通过TCP连接5222port进行全双工通信.
    • 2. XMPP 信息均包括在 XML streams中.一个XMPP会话, 開始于<stream> 标签, 并结束于</stream>标签.全部其它的信息都位于这俩标签之间.
    • 3. 出于安全目的考虑, 開始<stream>之后, 兴许的内容会被适度的使用 Transpor Layer Security (TLS) 协商传输 和强制性的 Simple Authentication 和 Security Layer (SASL) 协商传输.
    • 4. SASL协商完毕后, 一个新的 stream 将会被迅速打开, 它将会更加安全和保密.


    第一步: 打开 stream

    Client: client发送打开 stream 的片段到server, 请求一个新的 session.
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <stream:stream to='example.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>  
    这里 “example.com” 是client试图连接的server的域名.

    Server: Server 返回 XML stream, 以<stream:freatures> 开头, 包括要求 TLS 或者 SASL 协商谈判之中的一个, 或者2个都要求.
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <stream:features>  
    2.     <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>  
    3.         <required/>  
    4.     </starttls>  
    5.     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>  
    6.         <mechanism>DIGEST-MD5</mechanism>  
    7.         <mechanism>PLAIN</mechanism>  
    8.         <mechanism>EXTERNAL</mechanism>  
    9.     </mechanisms>  
    10. </stream:features>  

    第二步: 加密和认证.

    2.1 假设server须要 TLS 交涉.


    Client: client发送 STARTTLS 到server.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  

    Server: server返回消息显示 TLS 已被同意:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  

    或者 TLS失败了:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/> </stream:stream>  

    在失败的情况下, server会关闭 TCP 连接.

    Client: 假设 TLS 已被server正确处理, client发送请求一个新的 session:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>  

    Server: server响应一个 XML stream, 指示是否须要 SASL 交涉.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'>  
    2. <stream:features>  
    3.     <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>  
    4.         <mechanism>DIGEST-MD5</mechanism>  
    5.         <mechanism>PLAIN</mechanism>  
    6.         <mechanism>EXTERNAL</mechanism>  
    7.     </mechanisms>  
    8. </stream:features>  

    2.2 SASL 交涉

    Client client须要选择一个server上有效的认证方式来携带SASL交涉数据, 上面的情况, “DIGEST-MD5“, “PLAIN” 和 “EXTERNAL” 是一些可选项.

    “PLAIN” 认证模式是三者之中最简单的了. 它是这样工作的:

    Client: client依照自己选择的认证模式发送一个将username和password以base64编码的 stream. username和password按这样的格式组织:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. “UserNamePassword”.  

    比如我想以username为“mbed@ceit.org”登录, password是“mirror”. 那么, 在进行base64编码之前, username和password依照上面的格式组织为一个新的字符串,“mbedmirror”, 再进行base64编码, 得到字符串“AG1iZWQAbWlycm9y”.


    然后, client发送下列 stream 到server.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AG1iZWQAbWlycm9y</auth>  

    Server: 假设server接受了认证信息, server会发回 带 “success” 标签的 stream.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>  
    或者:

    Server: 假设password和username不匹配, 或者上面的base64编码有错误, server发回错误信息的 stream.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <failure xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>  

    “DIGEST-MD5” 认证模式的详细方法能够在这里找到: http://www.ietf.org/rfc/rfc2831.txt.

    第三步: 资源绑定(可选)


    Client: client要求server绑定一个资源(能够理解为client的类型, 比方电脑, 手机, Web应用等):
    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq type='set' id='bind_1'>  
    2.     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'/>  
    3. </iq>  

    或者
    Client: client自己绑定一个资源:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq type='set' id='bind_2'>  
    2.     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>  
    3.         <resource>someresource</resource>  
    4.     </bind>  
    5. </iq>  

    Server: server发回另外一个<iq>片段, 假设“type” 标签的内容是“result”, 说明绑定是成功的, 否则说明绑定失败.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq type='result' id='bind_2'>  
    2.     <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'>  
    3.         <jid>somenode@example.com/someresource</jid>  
    4.     </bind>  
    5. </iq>  

    第四步: 请求一个新的session


    在 SASL 交涉完毕之后或者可选资源绑定之后, client必须建立一个 session 来開始即时消息发送和接收.

    Client: client向server发送请求:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq to='example.com' type='set' id='sess_1'>  
    2.     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>  
    3. </iq>  
    Server: server发回一个<iq> 片段表明 session 是否成功创建.

    创建成功的消息类似于:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq from='example.com' type='result' id='sess_1'/>  

    假设server未能创建 session, server将会回复一个例如以下消息或者其它类型的错误消息.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <iq from='example.com' type='error' id='sess_1'>  
    2.     <session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>  
    3.     <error type='auth'>  
    4.         <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>  
    5.     </error>  
    6. </iq>  

    第五步: client和server交换 XMPP 片段


    假设以上步骤均成功完毕, 那么client就能够发送 XMPP 片段到server和接收 XML stream了.

    client能够发送 <iq> 片段来向server请求 roster 或者其它信息. 并能够使用 <presence> 片段来改变client的 presence 状态(比方在线, 离开等)

    即时消息和其它的负载能够通过发送 <message> 片段来完毕.


    第六步: 关闭 stream


    最后, 假设client想要结束聊天和关闭 XMPP session, client须要发送一个关闭 stream的片段到server.

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <presence type='unavailable'/>  
    2. /stream:stream>  

    然后, server将会改变client的 presence 状态为 “Offline” , 而且关闭 和client的 TCP 连接.

  • 相关阅读:
    September 29th 2017 Week 39th Friday
    September 28th 2017 Week 39th Thursday
    September 27th 2017 Week 39th Wednesday
    September 26th 2017 Week 39th Tuesday
    September 25th 2017 Week 39th Monday
    September 24th 2017 Week 39th Sunday
    angular2 学习笔记 ( Form 表单 )
    angular2 学习笔记 ( Component 组件)
    angular2 学习笔记 ( Http 请求)
    angular2 学习笔记 ( Router 路由 )
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6884059.html
Copyright © 2011-2022 走看看