标签:
SIMPLE(SIP Instant Messaging and Presence LeveragingExtensions)是SIP的扩展协议,其资料找到一篇中文的文档及一篇RFC3428文档,中文的文档主要讲是对SIMPLE协议的presence介绍,FC3428主要讲对SIP扩展的即时通讯的介绍。
通过查找资料得知应用此协议的软件:原MSN版本4(现已无法使用),无法抓取SIMPLE协议的数据包;外国软件Bria,可以使用,但只能抓取打电话的SIP协议数据包,其它通讯聊天及视频会议的情景需要付费才能使用,因此也未抓取到数据包。
下面从Presence与InstantMessage两个模块介绍SIMPLE协议。
“presence”,也作“presenceinformation”,中文一般译为“呈现”,用以传达某一用户通过一组设备进行通信的能力和意愿。拿常见的MSN Messenger来举例,MSN v7.5为用户提供的可选状态有:联机、忙碌、马上回来、离开、接听电话、外出就餐和显示为脱机。这些状态便称为“presence 状态”,它们表征了用户当前处于的某种状态和用户进行通信的意愿。同时,这些状态还反映出与该用户进行通信的能力,比如若用户处于“脱机”状态的话,别的用户便不能用即时消息与之通信。因此,一个最简单的presence过程如下:一个用户(称为watcher)订阅(SUBSCRIBE)他感兴趣的另一用户(presentity)的presence状态,presentity接受订阅请求。以后presentity的状态发生变化之后他会发布(PUBLISH)自己的新状态,这个新状态会通知(NOTIFY)给watcher。(注:watcher、presentity等概念严格上来说指网络中的通信实体,这里为了解释方便将他们进行了扩展,也泛指人)
SIMPLE 符合 RFC2778 提出的 presence 模型,其结构图如下:
各实体功能如下:
Presence Service:接收、存储和分发presence information。Presence Service既可以是一个物理实体上的server,也可以只是presentity和watcher之间的直接通信。在具体实现中前者比较常见,后者是P2P的模式。
Presentity:用于提供presence information给Presence Service。
Watcher:向Presence Service请求获取Presentity的presence information或自身的watcher information。
Principal:指单个的人、程序或者设备,也可以是人、程序、设备的集合体。对于Presence Service 来说,各个Principal是不同的。
Presence User Agent:为Principal提供手段来操作0个或者多个Presentity,Principal操作Presence User Agent改变Presentity的状态。是Principal和Presentity交互的interface。
Watcher User Agent:类似Presence User Agent,Principal通过其来操作0个或多个Watcher,Watcher收到Presentity的新状态之后也通过Watcher User Agent呈现给Principal。
Presence Protocol:定义了Presentity和Presence Service,Watcher和Presence Service之间交换消息的一组标准。
情景设定:
假设本 presence 系统的域名是“cintel.net.cn”,系统中有一下几个实体:
Presence Server:系统中的presence服务器。负责接收和处理所辖域内用户的 订阅、发布状态请求;通知用户其订阅的状态信息发生改变;处理添加和删除好友;处理添加和删除黑白名单;管理维护所辖域内用户数据等。其 SIP-URI 为“sip:ps.cintel.net.cn”,FQDN为“ ps.cintel.net.cn”
A:代表用户A。在网络中是一个终端(可以是软终端或者硬终端),集watcher和presentity实体功能于一身。用于向Presence Server发送订阅(SUBSCRIBE)别的用户状态的请求;自己状态发生变化时向PresenceServer发布(PUBLISH)新的状态;接收和处理Presence Server发来的状态通知(NOTIFY);利用XCAP协议发送和接收添加删除好友、黑白名单的请求和响应等。其在系统中的AOR为“sip:A@ps.cintel.net.cn”,FQDN为“ a.cintel.net.cn”。
B:与A类似,AOR为“sip:B@ps.cintel.net.cn”,FQDN为“b.cintel.net.cn”。
C:与A类似,AOR为“sip:C@ps.cintel.net.cn”,FQDN为“c.cintel.net.cn”。
由于pidf只定义了基本的状态,如basic元素中的“open”和“close”两种状态(前者表示当前的通信状态可用(最常见的就是表示可以发送即时消息),后者表示当前的通信状态不可用),详细一点的状态信息比如“busy”、“away”等没有明确规定。要表示这种状态由具体实现决定,一般都是进行扩展,如teltel是在note元素中表达这种信息。另外,rpidf对pidf进行了扩展,提供丰富的各种信息。此文档中在PIDF的“status”元素下扩展“im”元素,来表示具体的状态(假设有“联机”、“忙碌”、“离开”和“显示为脱机”四种状态,对应的im元素值分别为“online”、“busy”、“away”
2.1.2.1.1情景说明
A拥有且仅拥有B和C两位好友,也就是说A有权订阅B和C的状态信息。终端A启动,向Presence Server发送订阅其好友列表的请求(好友列表URI格式为“sip:username-list@ps.cintel.net.cn”)。假设B一开始处于不在线状态,C至始至终处于“open”状态。PresenceServer经过验证将B和C的状态信息通知A。一段时间后B登陆,其状态发生了变化,于是B向Presence Server发布其新状态。Presence Server处理之后将B的新状态通知A,A处理之后会正确显示出B的新状态。在每次订阅超时之前A会重新发送一个订阅请求刷新他的订阅。A退出,向Presence Server发送取消订阅的请求,Presence Server接收并发送最后一次状态通知。
2.1.2.1.2 SIP消息流程图
2.1.2.1.3消息流说明
1、A 启动,向Presence Server发送订阅其好友列表状态的请求。
M1消息如下:
SUBSCRIBE[D1] sip:A-list@ps.cintel.net.cn[D2] SIP/2.0[D3]
Via[D4] :SIP/2.0/UDP[D5] a.cintel.net.cn[D6] ;
branch=z9hG4bKwYb6QREiCL
Max-Forwards:70[D7]
To: <sip:A-list@ps.cintel.net.cn >[D8]
From:<sip:A@ps.cintel.net.cn>;[D9] tag=ie4hbb8t[D10]
Call-ID:cdB34qLToC@a.cintel.net.cn[D11]
CSeq: 1SUBSCRIBE[D12]
Contact:<sip:a.cintel.net.cn>[D13]
Event:presence[D14]
Expires:3600[D15]
Supported:eventlist[D16]
Accept:application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/relate[D17]
Content-Length:0[D18]
2、向A发送“200 OK”,表明此次订阅已经得到 验证和授权,订阅操作成功。
M2消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCL
To: < sip:A-list@ps.cintel.net.cn >;tag=zpNctbZq
From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 1 SUBSCRIBE
Contact: <sip:ps.cintel.net.cn>
Expires: 3200
Require:eventlist[D19]
Content-Length: 0
3、根据RFC 3265的要求,Presence Server在返回一个针对SUBSCRIBE的200 OK响应之后会立即给A发送NOTIFY通知其已经知道的好友的状态。
M3 消息如下:
NOTIFY [D20] sip:a.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmm
Max-Forwards: 70
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5768 NOTIFY
Contact:<sip:ps.cintel.net.cn>
Event: presence
Subscription-State[D21] : active;expires=3200
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<nXYxAE@ps.cintel.net.cn>";
boundary="50UBfW7LSCVLtggUPe5z"
Content-Length: 1560
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding:binary[D22]
Content-ID: <nXYxAE@ ps.cintel.net.cn >
Content-Type:application/rlmi+xml;charset="UTF-8"[D23]
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:A-list@ps.cintel.net.cn"
version="1" fullState="true">
<name language="en">Buddy List of A</name>
<name language="de">Liste der Freunde of A</name>
<resource uri="sip:B@ps.cintel.net.cn">
<name>B</name>
<instance id="juwigmtboe" state="active"
cid="B@ps.cintel.net.cn"/>
</resource>
<resource uri="sip:C@ps.cintel.net.cn">
<name>C</name>
<instance id="hqzsuxtfyq" state="active"
cid="C@ps.cintel.net.cn"/>
</resource>
</list>
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <B@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:B@ps.cintel.net.cn">
<tuple id="sg89ae">
<status>
<basic>closed</basic>
<im>offline[D24] </im>
</status>
</tuple>
</presence>
--50UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <C@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:C@ps.cintel.net.cn">
<tuple id="slie74">
<status>
<basic>open</basic>
<im>online[D25] </im>
</status>
<contactpriority="1.0">sip:C@ps.cintel.net.cn</contact>
</tuple>
</presence>
--50UBfW7LSCVLtggUPe5z—
4、A收到NOTIFY之后进行处理,将B和C的状态正确显示出来,并返回“200 OK”完成NOTIFY 事务。M4 消息如下:
SIP/2.0200 OK
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmm
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5768 NOTIFY
Contact: <sip:a.cintel.net.cn>
Content-Length: 0
5、一段时间后B登陆,B向Presence Server发布其新的状态信息。类似于SUBSCRIBE方法, PUBLISH(PUBLISH不创建dialog)也要头字段Expires和Event。比较特殊的是PUBLISH中不包含Contact头字段。M5 消息如下:
PUBLISH [D26] sip:B@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP b.cintel.net.cn;branch=z9hG4bK652hsge
Max-Forwards: 70
To: <sip:B@ps.cintel.net.cn>
From: <sip:B@ps.cintel.net.cn>;tag=1234wxyz
Call-ID: 81818181@b.cintel.net.cn
CSeq:1 PUBLISH
Expires: 3600
Event: presence
Content-Type: application/pidf+xml
Content-Length: 224
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:B@ps.cintel.net.cn">
<tuple id="slie74">
<status>
<basic>open</basic>
<im>online</im>
</status>
</tuple>
</presence>
6、Presence Server收到PUBLISH请求之后将B的新状态保存在数据库中,并返回200响应。类似于SUBSCRIBE,也包含一个Expires头字段,用法也一 样。另外,此200响应中还应该有一个SIP-ETag 头字段,用来标识和验证B的下一次 PUBLISH。
M6消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP b.cintel.net.cn;branch=z9hG4bK652hsge
To: <sip:B@ps.cintel.net.cn>;tag=1a2b3c4d
From: <sip:B@ps.cintel.net.cn>;tag=1234wxyz
Call-ID: 81818181@b.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3200
SIP-ETag:dx200xyz[D27]
Content-Length: 0
7、Presence Server将B的新状态NOTIFY给A。此NOTIFY既可以包含全部好友的状态信息,也可以只包含状态发生变化的好友的状态信息,这里采用的 是后者。
M7消息如下:
NOTIFY sip:a.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmn
Max-Forwards: 70
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5769 NOTIFY
Contact: <sip:ps.cintel.net.cn>
Event: presence
Subscription-State:active;expires=2000
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<nXYxAF@ps.cintel.net.cn>";
boundary="60UBfW7LSCVLtggUPe5z"
Content-Length: 1560
--60UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <nXYxAF@ ps.cintel.net.cn >
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:A-list@ps.cintel.net.cn"
version="2" fullState="false">
<name language="en">Buddy List of A</name>
<name language="de">Liste der Freunde of A</name>
<resource uri="sip:B@ps.cintel.net.cn">
<name>B</name>
<instance id="juwigmtbof" state="active"
cid="B@ps.cintel.net.cn"/>
</resource>
</list>
--60UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <B@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:B@ps.cintel.net.cn">
<tuple id="sg89af">
<status>
<basic>open</basic>
<im>online</im>
</status>
</tuple>
</presence>
--60UBfW7LSCVLtggUPe5z
8、A收到NOTIFY之后将 B 的新状态显示出来,并返回 200 完成 NOTIFY 事 务。
M8 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmn
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5769 NOTIFY
Contact: <sip:a.cintel.net.cn>
Content-Length: 0
9、一段时间之后, A 为了防止对好友列表的订阅超时而失效,再次发了一个带 Expires 头字段的 SUBSCRIBE,以刷新前一次订阅,注意这个SUBSCRIBE 仍要在前一个创建的对话(dialog)中。
M9 消息如下:
SUBSCRIBE sip:A-list@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCM
Max-Forwards: 70
To: < sip:A-list@ps.cintel.net.cn >;tag=zpNctbZq
From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 2 SUBSCRIBE
Contact: <sip:a.cintel.net.cn>
Event: presence
Expires: 3600
Supported: eventlist
Accept: application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/related
Content-Length: 0
10、Presence Server收到SUBSCRIBE请求之后经判断得知是一个刷新订阅的请求,再次根据presence rules授权并选取适当的Expires值后返回给 A 一个 200 响应。
M10 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCM
To: < sip:A-list@ps.cintel.net.cn >;tag=zpNctbZq
From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 2 SUBSCRIBE
Contact: <sip:ps.cintel.net.cn>
Expires: 3200
Require:eventlist
Content-Length: 0
11、 Presence Server 立即返回 NOTIFY 通知 A 当前其全部好友的 presence 状态。
M11 消息如下:
NOTIFYsip:a.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmo
Max-Forwards: 70
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5770 NOTIFY
Contact: <sip:ps.cintel.net.cn>
Event: presence
Subscription-State: active;expires=3200
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<nXYxAG@ps.cintel.net.cn>";
boundary="70UBfW7LSCVLtggUPe5z"
Content-Length: 1560
--70UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <nXYxAG@ps.cintel.net.cn >
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:A-list@ps.cintel.net.cn"
version="3" fullState="true">
<name language="en">Buddy List of A</name>
<name language="de">Liste der Freunde of A</name>
<resource uri="sip:B@ps.cintel.net.cn">
<name>B</name>
<instance id="juwigmtbog" state="active"
cid="B@ps.cintel.net.cn"/>
</resource>
<resource uri="sip:C@ps.cintel.net.cn">
<name>C</name>
<instance id="hqzsuxtfyh" state="active"
cid="C@ps.cintel.net.cn"/>
</resource>
</list>
--70UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding:binary
Content-ID: <B@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:B@ps.cintel.net.cn">
<tuple id="sg89ag">
<status>
<basic>open</basic>
<im>online</im>
</status>
</tuple>
</presence>
--70UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <C@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:C@ps.cintel.net.cn">
<tuple id="slie76">
<status>
<basic>open</basic>
<im>online</im>
</status>
<contactpriority="1.0">sip:C@ps.cintel.net.cn</contact>
</tuple>
</presence>
--70UBfW7LSCVLtggUPe5z—
12、A 收到 NOTIFY 消息之后刷新所有好友的 presence 状态并返回 200 响应完成 NOTIFY 事务。
M12 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmo
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5770 NOTIFY
Contact: <sip:a.cintel.net.cn>
Content-Length: 0
13、 后来, A 终端退出,会触发一个取消订阅的请求,在 SIMPLE 中这是通过置 Expires 头字段值为 0 来完成的。此 SUBSCRIBE 仍属于第一个创建的对话 (dialog)。
M13 消息如下:
SUBSCRIBE sip:A-list@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCN
Max-Forwards: 70
To: < sip:A-list@ps.cintel.net.cn >;tag=zpNctbZq
From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 3 SUBSCRIBE
Contact: <sip:a.cintel.net.cn>
Event: presence
Expires: 0
Supported: eventlist
Accept: application/pidf+xml
Accept: application/rlmi+xml
Accept: multipart/related
Content-Length: 0
14、Presence Server 接受取消订阅的请求,向A返回Expires值为 0 的 200 响应。
M14 消息如下:
SIP/2.0200 OK
Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCN
To: < sip:A-list@ps.cintel.net.cn >;tag=zpNctbZq
From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 3 SUBSCRIBE
Contact: <sip:ps.cintel.net.cn>
Expires: 0
Require: eventlist
Content-Length: 0
15、Presence Server 会给 A 发最后一次 NOTIFY,通知其所有好友的状态,并且 Subscription-State 的 expires 参数值设为 0,表示订阅有效时间已经结束,这 是最后一次 presence 状态发布。
M15 消息如下:
NOTIFYsip:a.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmp
Max-Forwards: 70
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5771 NOTIFY
Contact: sip:ps.cintel.net.cn
Event:presence
Subscription-State: active;expires=0
Require: eventlist
Content-Type: multipart/related;type="application/rlmi+xml";
start="<nXYxAH@ps.cintel.net.cn>";
boundary="80UBfW7LSCVLtggUPe5z"
Content-Length: 1560
--80UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <nXYxAH@ps.cintel.net.cn >
Content-Type: application/rlmi+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<list xmlns="urn:ietf:params:xml:ns:rlmi"
uri="sip:A-list@ps.cintel.net.cn"
version="4" fullState="true">
<name language="en">Buddy List of A</name>
<name language="de">Liste der Freunde of A</name>
<resource uri="sip:B@ps.cintel.net.cn">
<name>B</name>
<instance id="juwigmtboh" state="active"
cid="B@ps.cintel.net.cn"/>
</resource>
<resource uri="sip:C@ps.cintel.net.cn">
<name>C</name>
<instance id="hqzsuxtfyi" state="active"
cid="C@ps.cintel.net.cn"/>
</resource>
</list>
--80UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <B@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:B@ps.cintel.net.cn">
<tuple id="sg89ah">
<status>
<basic>open</basic>
<im>online</im>
</status>
</tuple>
</presence>
--80UBfW7LSCVLtggUPe5z
Content-Transfer-Encoding: binary
Content-ID: <C@ps.cintel.net.cn>
Content-Type: application/pidf+xml;charset="UTF-8"
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:C@ps.cintel.net.cn">
<tuple id="slie77">
<status>
<basic>open</basic>
<im>online</im>
</status>
<contact priority="1.0">sip:C@ps.cintel.net.cn</contact>
</tuple>
</presence>
--80UBfW7LSCVLtggUPe5z—
16、 A 收到最后一个 NOTIFY 之后返回 200 完成 NOTIFY 事务。
M16 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKMgRenTETmp
From: <sip:A-list@ps.cintel.net.cn>;tag=zpNctbZq
To: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t
Call-ID: cdB34qLToC@a.cintel.net.cn
CSeq: 5771 NOTIFY
Contact: <sip:a.cintel.net.cn>
Content-Length: 0
2.1.2.2.1情景说明
A 想添加 B 为好友,向 B 发起一个订阅 presence 状态的请求。 B 在线,且接受 了 A 的请求。于是, A 成功将 B 加为好友并且能够观察 B 的 presence 状态信息。
2.1.2.2.2SIP消息流程图
2.1.2.2.3消息流说明
注:上图中M开头的是SIP消息,H开头的是HTTP消息。验证(authentication)没有包含在内。 假设之前代表 A 的好友列表的 resource-list的document已经和维护所有列表资源 的 rls-resources 的 document 已经关联好。存储在服务器端的这两个document 内容如下( XCAP root 为“ http://ps.cintel.net.cn”):
Content ofresource-list document:
<?xml version="1.0"encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<list name="buddies">
<entryuri="sip:C@ps.cintel.net.cn">
<display-name>C</display-name>
</entry>
</list>
</resource-lists>
Content ofrls-resources document:
<?xmlversion="1.0" encoding="UTF-8"?>
<rls-services xmlns="urn:ietf:params:xml:ns:rls-services"
xmlns:rl="urn:ietf:params:xml:ns:resource-lists"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<service uri="sip:A-list@ps.cintel.net.cn">
<resource-list>http://ps.cintel.net.cn/resource-lists/users/A/buddies.xml/~~/
resource-lists/list%5b@name=%22buddies%22%5d</resource-list>
<packages>
<package>presence</package>
</packages>
</service>
</rls-services>
注:上面的内容虽然表示的时候用的是 XML 格式,并且术语上还说存在 document 中,但是这个 document 是广义的,不仅仅指一个文本文档,事实上,一般来说 这种信息都是存储在数据库中的,这就需要一个将 XML 数据映射到数据库数据 的过程。
1、A 想添加 B 为好友,将 B 添加到其本地好友列表中,同时产生一个 SUBSCRIBE 消息发送给 Presence Server。此外, A 还会向 Presence Server 发 送一个基于 XCAP 协议的 HTTP 消息 PUT,用来添加 B 到服务器端的好友 列表中以保持两边的列表信息同步。
H1 消息如下:
PUT
/resource-lists/users/A/buddies.xml
/~~/resource-lists/list%5b@name=%22buddies%22%5d/entry HTTP/1.1
Content-Type:application/xcap-el+xml
Host: ps.cintel.net.cn
<entry uri="sip:B@ps.cintel.net.cn">
<display-name>B</display-name>
</entry>
2、 Presence Server 收到“H1: PUT”之后,将B添加到A的好友列表中。收到“ M1:SUBSCRIBE”后,检查B的presence rules,得知对来自 A 的订阅的本地策略未知,于是在 A 的好友列表中将B的订阅状态设置为“ pending”, 并且返回“ 202 Accepted”,表示收到订阅请求并被理解,但是还没得到授权。
3、Presence Server向 A 发送NOTIFY通知其对B的订阅请求处于“pending”状态。并且,在B的watcherinfo信息中添加一条 A 的记录,状态为“pending”,Presence Server会向B发送NOTIFY消息通知,消息体类型为“ application/watcherinfo+xml”,典型的消息体如下:
<?xmlversion="1.0" encoding="UTF-8"?>
<watcherinfo xmlns="urn:ietf:params:xml:ns:watcherinfo"
version="1" state="partial">
<watcher-list resource="sip:B@ps.cintel.net.cn"package="presence">
<watcher id="77ajsyy76" event="subscribe"
status="pending">sip:A@ps.cintel.net.cn</watcher>
</watcher-list>
</watcherinfo>
4、B 的终端收到“ M4: NOTIFY”之后立即返回 200 完成 NOTIFY 事务。同时 向 B 用户弹出提示: A 请求加好友。在这里,终端可以给 B 用户提供两种选 择:仅仅接受 A 的请求或者接受订阅请求的同时还将 A 加为好友。如果 B 选择前者,那么 B 终端只需向 Presence Server 发送一个添加 A 到 B 的白名 单中的 HTTP 请求 PUT(这种消息体格式为“ application/auth-policy+xml”)。如果 B 用户选择后者, B 终端在本地好友列表中添加 A 用户, 并且除了向 Presence Server 发送加白名单的 PUT 请求, 还需要发送一个将 A 添加为 B 好友的 PUT 请求和一个订阅 A 的 presence 状态的 SUBSCRIBE 请 求(这次 B 加 A 好友的过程与 A 加 B 一样,只是方向相反)。这里不管 B 用户选择前者还是后者都不再描述与前面过程类似的消息,只描述 A 加 B 好 友的那部分后续消息。
H3 消息如下:
PUT
/pres-rules/users/B/presrules.xml/~~/rule-set/
rule?xmlns(cr=%22urn:ietf:params:xml:ns:common-policy%22) HTTP/1.1
Content-Type:application/xcap-el+xml
Host: ps.cintel.net.cn
<cr:rule id="1">
<cr:conditions>
<cr:identity>
<cr:id entity="A@ps.cintel.net.cn"/>
</cr:identity>
</cr:conditions>
<cr:actions>
<sub-handling>allow</sub-handling>
</cr:actions>
<cr:transformations>
<provide-services>
<all-services/>
</provide-services>
<provide-unknown-attributename="new:foo">true</provide-unknown-attribute>
</cr:transformations>
</cr:rule>
5、Presence Server 收到“ H3: PUT”之后,返回一个 200 响应,并且将 A 添加到 B 的白名单中,将 A 的好友列表中 B 的订阅状态改为“active”。然后查询 B 的当前 presence 状态,构造 NOTIFY 消息通知 A。 6. A 收到响应之后返回 200 完成 NOTIFY 事务,并将 B 的 presence 状态显示出 来。 说明:如果 A 加 B 好友的时候 B 不在线,消息流程图中 M3 之前(含 M3)的消息 不变,只是Presence Server 在
B 的 watcherinfo 中添加 A 的记录之后不会立即 给 B 发送 NOTIFY,而是等到B登陆之后发送。如果 B 收到“ M4: NOTIFY”之后不接受 A 的订阅请求,随即返回的SIP消 息还是 200 (事实上这个 200 响应是在 B 用户做出决定之前终端就自动发的,它仅表明NOTIFY 消息被接受,立即返回 200 是为了维持 NOTIFY 事务,因 为这种事务不能时间过长)。但是在“ H3:PUT”中不是添加到白名单的信息, 而是添加到灰名单。PresenceServer 收到这个请求后如何处理由实现决定,可以构造一个带“
Subscription-State: terminated; reason=rejected”头字段的 NOTIFY 消息给 A, A 终端收到这个消息后将 B 在本地好友列表置于临时删 除状态,并且向 A 发送一个 HTTP 的 DELETE 请求,用以删除 PresenceServer 端 A 好友列表中的 B 记录。 Presence Server 收到请求确实删除 B 并返回 200 之后 A 的终端再正式在本地好友列表中删除 B。
2.1.2.3.1情景说明
假设 C 用户已被授权订阅了 B 的 presence 状态, A 在 B 不在线的时候请求订阅 B 的状态。后来 B 登陆,向 Presence Server 发出订阅其 watcherinfo 的请求,Presence Server 接受请求,通知其最新的 watcherinfo 状态,由于 A 的订阅尚未授权,因此会提示 B 用户鉴权。
2.1.2.3.2SIP消息流程图
2.1.2.3.3消息流说明
Presence 系统对 watcherinfo 的处理和 presence 类似,只是事件包(event package) 变为*.winfo。
1、 B 终端启动,向 Presence Server发送 SUBSCRIBE 请求,订阅自身的 watcherinfo 信息。注意其 Event 头字段的值为 presence.winfo。
M1 消息如下:
SUBSCRIBE sip:B@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP b.cintel.net.cn;branch=z9hG4bKnashds7
From: <sip:B@ps.cintel.net.cn>;tag=123aa9
To: <sip:B@ps.cintel.net.cn>
Call-ID: 9987@b.cintel.net.cn
CSeq: 1 SUBSCRIBE
Contact: <sip:b.cintel.net.cn>
Event: presence.winfo
Expires: 3600
Accept: application/watcherinfo+xml
Max-Forwards: 70
Content-Length: 0
2、Presence Server 收到请求之后进行鉴权和授权,接受之后返回 200 响应。
M2 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP b.cintel.net.cn;branch=z9hG4bKnashds7
From: <sip:B@ps.cintel.net.cn>;tag=123aa9
To: <sip:B@ps.cintel.net.cn>;tag=xyzygg
Call-ID: 9987@b.cintel.net.cn
CSeq: 1 SUBSCRIBE
Contact: <sip:ps.cintel.net.cn>
Expires: 3200
Content-Length: 0
3、 Presence Server 查询出 B 的 watcherinfo 信息( A 处于“ pending”状态, C 处 于“ active”状态),构造成 NOTIFY 消息通知 B。此 NOTIFY 消息体的格式 是“application/watcherinfo+xml”。注意消息体中 watcherinfo 元素的属性 version 随着每次发布递增,一般第一次是 0。第一次发布的时候应该包含所 有记录,因此 state 属性的值为“ full”,后续的发布既可以只包含部分改变的 记录也可以包含全部,由实现来决定。
M3 消息如下:
NOTIFYsip:B@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKnasaii
From: <sip:B@ps.cintel.net.cn>;tag=xyzygg
To: <sip:B@ps.cintel.net.cn>;tag=123aa9
Call-ID: 9987@b.cintel.net.cn
CSeq: 1288 NOTIFY
Contact: <sip:ps.cintel.net.cn>
Event: presence.winfo
Subscription-State: active;expires=3200
Max-Forwards: 70
Content-Type: application/watcherinfo+xml
Content-Length: 446
<?xml version="1.0" encoding="UTF-8"?>
<watcherinfo xmlns="urn:ietf:params:xml:ns:watcherinfo"
version="0" state="full">
<watcher-list resource="sip:B@ps.cintel.net.cn"package="presence">
<watcher id="77ajsyy76" event="subscribe"
status="pending">sip:A@ps.cintel.net.cn</watcher>
<watcher id="77ajsyy77" event="approved"
status="active">sip:C@ps.cintel.net.cn</watcher>
</watcher-list>
</watcherinfo>
4、B 收到 NOTIFY 之后返回 200。因为 NOTIFY 消息体中 A 的订阅状态为 “ pending”,因此 B 终端会弹出提示请求 B 用户鉴权。
M4 消息如下:
Presence Overview
SIP/2.0 200 OK
Via: SIP/2.0/UDP ps.cintel.net.cn;branch=z9hG4bKnasaii
From: <sip:B@ps.cintel.net.cn>;tag=xyzygg
To: <sip:B@ps.cintel.net.cn>;tag=123aa9
Call-ID: 9987@b.cintel.net.cn
CSeq: 1288 NOTIFY
Contact: <sip:b.cintel.net.cn>
Content-Length: 0
2.1.2.4.1情景说明
假设 A 有两位好友: B 和 C, B 一直在线, C 不在线。 A 登陆,向 Presence Server 发布其 presence 状态,由于 C 不在线, Presence Server 只通知 B A 的 presence 状 态发生变化。 A 经一次状态改变和刷新最后发一个取消发布的 PUBLISH 退出系统。
2.1.2.4.2SIP消息流程图
2.1.2.4.3消息流说明
SIMPLE 规范中把发布(publication)分为四种:Initial、Modify、Refresh 和 Remove, 分别代表初始化、修改、刷新和删除发布(publication)。
发布( publication)机制引入了 SIP-ETag 和 SIP-If-Match 头字段。对于每一个成功接受的 PUBLISH 消息, Presence Server 都会分配一个 entity-tag 并包含在 2xx 响应的 SIP-ETag 头字段中。而在下一次的 PUBLISH 消息中必须带上 SIP-If-Match 头字段,其值就是上次 PUBLISH 返回的 2xx 响应中 SIP-ETag 的 entity-tag。服务器收到这个 PUBLISH 请求之后会比较 SIP-If-Match
头字段的值和自己保存的 entity-tag。如果匹配,那么接受这个请求,否则拒绝该请求。
1、A 终端登陆此系统,向 PresenceServer 发送 PUBLISH(登陆后首次发送的 PUBLISH 是 Initial 类型的),发布自己的新状态。
M1 消息如下:
PUBLISHsip:A@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsge
Max-Forwards: 70
To: <sip:A@ps.cintel.net.cn>
From: <sip:A@ps.cintel.net.cn>;tag=1234wxyz
Call-ID: 81818181@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3600
Event: presence
Content-Type: application/pidf+xml
Content-Length: 246
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:A@ps.cintel.net.cn">
<tuple id="slie74">
<status>
<basic>open</basic>
<im>online</im>
</status>
</tuple>
</presence>
2、Presence Server 收到PUBLISH 请求之后进行鉴权(authentication)和授权(authorization)。接受之后保存A的新状态并为此次发布(publication)分配一个entity-tag,包含在 SIP-ETag 中返回 200。
M2 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsge
To: <sip:A@ps.cintel.net.cn>;tag=1a2b3c4d
From: <sip:A@ps.cintel.net.cn>;tag=1234wxyz
Call-ID: 81818181@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3200
SIP-ETag: dx200xyz
Content-Length: 0
3、查询 A 的 watcherinfo 得知已订阅 A 的 presence 状态的有 B 和 C,又查知 B 当前在线, C 不在线。于是 Presence Server 向 B 发 NOTIFY 通知 A 的新状态, B 收到之后返回 200。
4、 假设一段时间后 A 由于工作原因,将状态改为“忙”,于是终端 A 向 Presence Server 发送一个 Modify 类型的 PUBLISH,更新其状态。这个 PUBLISH 中包含一个 SIP-If-Match 头字段,其值为上一个 200 响应中 SIP-ETag 的值。
M5 消息如下:
PUBLISHsip:A@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgf
Max-Forwards: 70
To: <sip:A@ps.cintel.net.cn>
From: <sip:A@ps.cintel.net.cn>;tag=1235wxyz
Call-ID: 81818182@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3600
Event: presence
SIP-If-Match:[D1] dx200xyz
Content-Type: application/pidf+xml
Content-Length: 241
<?xml version="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:A@ps.cintel.net.cn">
<tuple id="slie74">
<status>
<basic>open</basic>
<im>busy[D2] </im>
</status>
</tuple>
</presence>
5.、Presence Server 收到请求之后比较 SIP-If-Match 与自己保存的 entity-tag 值, 结果一致,于是接受该请求,并调整 Expires 有效时间长度。保存 A 的新状 态并再次分配一个新的 entity-tag 包含在 SIP-ETag 中返回 200。
M6 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgf
To: <sip:A@ps.cintel.net.cn>;tag=1a2b3c4e
From: <sip:A@ps.cintel.net.cn>;tag=1235wxyz
Call-ID: 81818182@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3200
SIP-ETag: dx300xyz
Content-Length: 0
6、发 NOTIFY 消息给 B 通知其 A 的新状态,B 收到之后返回 200。
7、在上一次的发布(publication)超时前 A 重新发了 PUBLISH 消息,这是个 Refresh 类型的消息,关键的头字段是 Expires,且不含消息体。
M9 消息如下:
PUBLISHsip:A@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgg
Max-Forwards: 70
To: <sip:A@ps.cintel.net.cn>
From: <sip:A@ps.cintel.net.cn>;tag=1236wxyz
Call-ID: 81818183@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3600
Event: presence
SIP-If-Match: dx300xyz
Content-Length: 0
8、由于Refresh 类型的消息只是刷新发布(publication)的有效时间,并不改变 presence 状态。因此不需要向订阅 A 状态的用户发 NOTIFY 消息。 Presence Server 选取适当的 Expires 值并分配新的 entity-tag 之后返回 200。
M10 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgg
To: <sip:A@ps.cintel.net.cn>;tag=1a2b3c4f
From: <sip:A@ps.cintel.net.cn>;tag=1236wxyz
Call-ID: 81818183@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 3200
SIP-ETag: dx400xyz
Content-Length: 0
9、最后, A 退出系统,向 Presence Server 发送一个取消发布(publication)的 PUBLISH 请求。该请求没有消息体, Expires 值为 0。
M11 消息如下:
PUBLISHsip:A@ps.cintel.net.cn SIP/2.0
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgh
Max-Forwards: 70
To: <sip:A@ps.cintel.net.cn>
From: <sip:A@ps.cintel.net.cn>;tag=1237wxyz
Call-ID: 81818184@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 0
Event: presence
SIP-If-Match: dx400xyz
Content-Length: 0
10、Presence Server 收到该请求之后删除 A 用户对应的一些发布( publication)数 据,如 expires 和 entity-tag。返回 200 完成 PUBLISH 事务。
M12 消息如下:
SIP/2.0 200 OK
Via: SIP/2.0/UDP a.cintel.net.cn;branch=z9hG4bK652hsgh
To: <sip:A@ps.cintel.net.cn>;tag=1a2b3c4g
From: <sip:A@ps.cintel.net.cn>;tag=1237wxyz
Call-ID: 81818184@a.cintel.net.cn
CSeq: 1 PUBLISH
Expires: 0
Content-Length: 0
11、虽然 A 退出时取消订阅的 PUBLISH 请求不带消息体,但是 A 的 presence 状 态发生了变化,变为“ Offline”。 Presence Server 会把新的离线状态保存下来 然后发 NOTIFY 消息通知 B, B 收到之后返回 200。承接上面的情景,这个 NOTIFY 的消息体典型如下:
<?xmlversion="1.0" encoding="UTF-8"?>
<presence xmlns="urn:ietf:params:xml:ns:pidf"
entity="sip:A@ps.cintel.net.cn">
<tuple id="slie74">
<status>
<basic>closed</basic>
<im>offline</im>
</status>
</tuple>
</presence>
2.1.2.5.1情景说明
B 是 A 的好友, A 将 B 删除, B 在线。
2.1.2.5.2SIP消息流程图
2.1.2.5.3消息流说明
1、 A 将 B 删除。 A 的终端会将 B 置上删除标记,并发送 XCAP 消息 DELETE 给 Presence Server,用以删除服务器端好友列表中的 B。
H1 消息如下:
DELETE[D1]
/services/resource-lists/users/A/buddylist.xml/
~~/resource-lists/list/list/
entry%5b@uri=%22sip:petri@example.com%22%5d HTTP/1.1
Host: ps.cintel.net.cn
2、经鉴权后将 B 从 A 的好友列表中删除,然后返回一个 200 响 应。
3、删除 B 还会影响 B 的 watcherinfo。Presence Server 会将 B 的 watcherinfo 中 A 的订阅状态改为“ terminated”,对应的事件(event)是“ deactivated”。然后 发 NOTIFY 通知 B, B 返回一个 200 消息。(当然,如果 B 当时不在线,那 么 Presence Server 会在 B 下次登陆的时候通知)。
2.1.2.6.1情景说明
用户可以自己添加或删除黑名单,用以阻止特定人员订阅自己的 presence 状态。
2.1.2.6.2SIP消息流程图
2.1.2.6.3消息流说明
1、 添加黑名单的方法相当简单,终端只需要向服务器发送一个 PUT 的 XCAP 消息,将消息体中的名单添加到 URI 指定的服务器端黑名单中。服务器端添 加成功之后返回 200。
2、 删除黑名单与添加黑名单类似,只是方法变为DELETE。
本部分介绍SIP的一个扩展的方法叫MESSAGE方法。MESSAGE需求body中一般带有即时通讯消息的内容。RFC2779中有即时通讯的MESSAGE方法的具体介绍。
使用范围:
在SIP环境中,一个IM会话是一个媒体会话,从INVITE开始到BYE结束。
操作情景:
当一个用户向另一个用户发送一个即时消息,发送者规定并发布一个MESSAGE方法的SIP请求。这个需求的Request-URI一般记录了接受者即时消息的地址,但是有可能是接受者在服务器中的注册的位置即设备地址。
这个请求可能会通过很多SIP代理服务器进行传输直至到达目的地址,目的地址的位置在CPIM及SIP特例中详细的进行了解释。在传输的过程中,每个代理服务器在基于有效的路由信息上有可能重写需求的URI。
临时和最终的反馈都会发送到发送者处。
用户1向用户2发送初始的IM消息,两个用户拥有相同的域,两个用户之间有一个代理。
2.2.1.3消息流说明
用户1发送信息到服务器domain.com,代理接收到这个请求并识别出domain.com服务器。它从数据库中查用户2并且找到从sip:user2@domain.com到sip:user2@user2pc.domain.com的绑定。它向user2转发需求。
消息F1:
MESSAGE[D1] sip:user2@domain.com SIP/2.0
Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse
Max-Forwards: 70
From: sip:user1@domain.com;tag=49583
To: sip:user2@domain.com
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Type: text/plain
Content-Length: 18
消息F2:
MESSAGEsip:user2@domain.com SIP/2.0
Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds
Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse;
received=1.2.3.4
Max-Forwards: 69
From: sip:user1@domain.com;tag=49394
To: sip:user2@domain.com
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Type: text/plain
Content-Length: 18
用户2接收到此消息,显示并产生回应,消息F3,并发送到代理:
SIP/2.0200 OK
Via: SIP/2.0/TCP proxy.domain.com;branch=z9hG4bK123dsghds;
received=192.0.2.1
Via: SIP/2.0/TCP user1pc.domain.com;;branch=z9hG4bK776sgdkse;
received=1.2.3.4
From: sip:user1@domain.com;tag=49394
To: sip:user2@domain.com;tag=ab8asdasd9
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Length: 0
代理接收该响应,并转发到下一个地址,user1pc.domain.com,产生消息F4:
SIP/2.0200 OK
Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse;
received=1.2.3.4
From: sip:user1@domain.com;;tag=49394
To: sip:user2@domain.com;tag=ab8asdasd9
Call-ID: asd88asd77a@1.2.3.4
CSeq: 1 MESSAGE
Content-Length: 0
使用message/cpimBodies
Message/cpim格式除了消息负载之外,元数据允许受到S/MIME的保护。在很多例子中,元数据在SIP的头域中是冗余的。所以,nessage/cpim添加值,通过扩展协议边界来对元数据进行保护。
[D1]请求方法,MESSAGE表示请求通讯
标签:
原文地址:http://blog.csdn.net/kevin_bobolkevin/article/details/51542005