zoukankan      html  css  js  c++  java
  • 飞信分析之五:用即时消息聊天时的协议交互过程(转)

    转自:http://hi.baidu.com/nathan2007/blog/item/1ee3823422ebbdb6d1a2d376.html

    以下分析基于Fetion 2006 beta 2.1.0.0,其SIP-C协议的版本是2.0。

    前面列出了飞信的SIP-C协议支持的所有SIP Method以及Header Field,下面就两个用户间的聊天,即互相发送文本消息来看看飞信通过SIP-C协议的工作过程。


    先看看RFC规定的SIP的建立会话的标准过程,在RFC3261中通过SIP建立会话的过程是这样子的:

                        atlanta.com . . . biloxi.com
                     .      proxy              proxy     .
                   .                                       .
           Alice's . . . . . . . . . . . . . . . . . . . . Bob's
          softphone                                        SIP Phone
             |                |                |                |
             |    INVITE F1   |                |                |
             |--------------->|    INVITE F2   |                |
             | 100 Trying F3 |--------------->|    INVITE F4   |
             |<---------------| 100 Trying F5 |--------------->|
             |                |<-------------- | 180 Ringing F6 |
             |                | 180 Ringing F7 |<---------------|
             | 180 Ringing F8 |<---------------|     200 OK F9 |
             |<---------------|    200 OK F10 |<---------------|
             |    200 OK F11 |<---------------|                |
             |<---------------|                |                |
             |                       ACK F12                    |
             |------------------------------------------------->|
             |                   Media Session                  |
             |<================================================>|
             |                       BYE F13                    |
             |<-------------------------------------------------|
             |                     200 OK F14                   |
             |------------------------------------------------->|
             |                                                  |

    上图中F1-F14分别是步骤的编号,而Medai Session过程在飞信中,就是文本聊天消息的传递过程了。在RFC3428中对标准SIP的扩展了一个Message方法,通过Message方法承载这种即时消息,这样,上图中的Media Session按RFC3428的规定,就是这样的:
               | F1 MESSAGE         |                         |
               |--------------------> | F2 MESSAGE             |
               |                      | ----------------------->|
               |                      |                         |
               |                      | F3 200 OK              |
               |                      | <-----------------------|
               | F4 200 OK           |                         |
               |<-------------------- |                         |
               |                      |                         |
               |                      |                         |
               |                      |                         |
            User 1                  Proxy                    User 2

    飞信是完全依照以上RFC的要求来实现这一过程来的。


    下面来看飞信具体实现的聊天过程是怎么样的。假定有这么一个聊天过程是:飞信用户A(飞信号为123456789,飞信用TCP方式工作在111.111.111.111:1111)双击好友列表中的飞信用户B(飞信号为987654321,飞信用TCP方式工作在222.222.222.222:2222),这时聊天窗口弹出,用户A对B发出:"Hello!测试“,然后用户A关闭了聊天窗口,结束了这次即时消息对话过程。

    我们看用户A这一端来看整个聊天过程中,用户A与服务器(SIP的Proxy Server)的交互过程是 (请对照上面RFC的SIP会话建立过程,另外,下面的红色字是表示数据的发送方向,蓝色字是全部的SIP消息,即TCP包的包体部分。):
    第一步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
    I fetion.com.cn SIP-C/2.0
    F: 123456789
    I: 16
    Q: 1 I
    T: sip:987654321@fetion.com.cn;p=1972
    K: text/html-fragment
    K: multiparty
    L: 137

    v=0
    o=-0 0 IN 111.111.111.111:1111
    s=session
    c=IN IP4 111.111.111.111:1111
    t=0 0
    m=message 1111 sip sip:123456789@fetion.com.cn;p=xxxx

    上面是发到服务器的第一条消息,是一个SIP协议的INVITE请求,发到飞信的服务器,服务器地址是221.130.45.203,端口8080,协议是TCP,上面的SIP消息就直接放在TCP的包中,UTF-8编码。

    消息的第1是请求行,I=INVITE(这缩写的标准在哪里?我还没找到来依据),fetion.com.cn是请求对象(又没用标准的uri),"sIP-C/2.0"是当前的SIP-C协议版本。
    第2行开始是消息头:"F"即From,标识从用户A(123456789)发出的请求(依然没用标准uri,应该是sip:123456789@xx.fetion.com.cn才对吧....);"I"即CallID,按标准的SIP的规定,这应该是一个随机产生的一个全局唯一的标识符,它应该在客户端和服务器整个交互的过程中保持不变,但在飞信的SIP-C协议中,这是一个序列号,第一次与8080端口建立连接发出第一个请求时,这个值为1,以后每次发出一个请求则加1;"Q"即CSeq,也就是Command Sequence,它由一个整数的序列号和一个SIP方法组成,SIP方法与这个消息的SIP方法相同,这个序列号在一个会话过程中每次加1,这样来标识SIP消息的顺序;"T"就是To啦,这里倒是用了标准uri的表示,"K"即Supported,表示客户端所支持扩展;"L"即Content-Length,就是消息体的长度。

    从v=0开始的是消息体,用SDP(Session Description Protocol)描述的,根据RFC:
    v= (protocol version),在目前飞信的INVITE中,固定的v=0
    o= (owner/creator and session identifier). 在目前飞信的INVITE中,前面是固定的,后面是发起人(用户A)的IP地址和端口
    s= (session name). 在目前飞信的INVITE中,固定的为s=session
    c=* (connection information - not required if included in all media).在目前飞信的INVITE中,除后面的发起人(用户A)的IP地址和端口外,前面是固定的。
    t= (time the session is active) 。在目前飞信的INVITE中,固定的为"t=0 0"
    m= (media name and transport address)。在目前飞信的INVITE中,"1111"是发起人的TCP端口,后面的sip:xxxxxxxx,是发起人的uri。


    第二步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
    SIP-C/2.0 100 Trying
    Q: 1 I
    T: sip:987654321@fetion.com.cn;p=xxxx
    I: 16


    这是服务器回过来的对第一步的INVITE消息的一个RESPONSE,所以,I=16,Q=1 I。表示正在查找用户B。

    第三步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
    SIP-C/2.0 200 OK
    Q: 1 I
    K: text/html-fragment
    K: multiparty
    T: sip:123456789@fetion.com.cn;p=xxx
    I: 16
    L: 135

    v=0
    o=-0 0 IN 222.222.222.222:2222
    s=session
    c=IN IP4 222.222.222.222:2222
    t=0 0
    m=message 2222 sip sip:987654321@fetion.com.cn;p=xxx

    这是服务器转过来的用户B对用户A的INVITE的回复,是:OK,其中222.222.222.222:2222是用户B的IP和端口。

    第四步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
    A fetion.com.cn SIP-C/2.0
    I: 16
    Q: 1 A
    T: sip:987654321@fetion.com.cn;p=xxx
    F: 123456789

    接着,用户A发出ACK消息。

    第五步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
    M fetion.com.cn SIP-C/2.0
    F: 123456789
    I: 16
    Q: 2 M
    T: sip:987654321@fetion.com.cn;p=xxxx
    C: text/html-fragment
    K: SaveHistory
    L: 121

    <Font Face='Arial' Color='-16777216' Size='9'>hello! </Font><Font Face='SimSun' Color='-16777216' Size='12'>测试</Font>

    这就是用户A向对方发的即时消息,内容是“hello!测试"。这里用的是SIP Message方法,消息体是XML表示的即时消息,消息头跟INVITE相似。

    第六步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
    SIP-C/2.0 200 OK
    Q: 2 M
    T: sip:123456798@fetion.com.cn;p=xxxx
    I: 16
    D: Mon, 01 Mar 2007 00:00:00 GMT
    XI: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

    这是用户B收到第五步发出的即时消息后回过来的RESPONSE,结果是OK,其中XI这个消息头域的MessageID。

    第七步:111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
    B fetion.com.cn SIP-C/2.0
    F: 123456789
    I: 16
    Q: 3 B
    T: sip:987654321@fetion.com.cn;p=xxxxx

    这是用户A开始关闭聊天窗口准备结束聊天了,向用户B发出了一个BYE的SIP请求消息。

    第八步:111.111.111.111:1111 <<<<<<<< 221.130.45.203:8080
    SIP-C/2.0 200 OK
    Q: 3 B
    T: sip:123456789@fetion.com.cn;p=xxxx
    I: 16

    这是最后用户B对对用户A发出的BYE的回复。


    在用户B那边,整个交互过程跟用户A这边对应,用户A在发出INVITE,要求和B会话,而用户B这边则是回应邀请。

    那发短信是怎么样的呢?也基本差不多,如发一个内容为test的短信到用户B时的SIP Message请求消息是这样的:
    111.111.111.111:1111 >>>>>>>> 221.130.45.203:8080
    M fetion.com.cn SIP-C/2.0
    F: 12345678
    I: 16
    Q: 1 M
    T: sip:987654321@fetion.com.cn;p=xxxx
    N: SendSMS
    L: 4

    test



    以上分析都是飞信通过TCP直连方式工作时的情况,飞信通过HTTP直连呢?工作过程跟上面完全一样,不同的是,连接的是221.130.45.203:80,协议是HTTP,采用的POST请求是:
    POST /ht/sd.aspx?t=s&i=2 HTTP/1.1
    POST的数据分就是上面一样的SIP消息了。

  • 相关阅读:
    定义Java类的数组的问题
    Ubuntu下将vim配置为Python IDE(转)
    Python数据结构-序列
    Python数据结构-元祖
    Python数据结构-字典
    Python数据结构-序表
    Python的控制结构(转)
    Python面向对象编程
    训练样本集的制作
    matlab读取指定路径下的图像
  • 原文地址:https://www.cnblogs.com/tulips/p/1403855.html
Copyright © 2011-2022 走看看