1.概述 2.基于SIMPLE协议的presence体系结构

1.概述

“presence”,也作“presence information”,中文一般译为“呈现”,用以传达某一用户通过一组设备进行通信的能力和意愿。拿常见的MSN Messenger来举例,MSN v7.5为用户提供的可选状态有:联机、忙碌、马上回来、离开、接听电话、外出就餐和显示为脱机。这些状态便称为“presence状态”,它们表征了用户当前处于的某种状态和用户进行通信的意愿。同时,这些状态还反映出与该用户进行通信的能力,比如若用户处于“脱机”状态的话,别的用户便不能用即时消息与之通信。因此,一个最简单的presence过程如下:一个用户(称为watcher)订阅(SUBSCRIBE)他感兴趣的另一用户(presentity)的presence状态,presentity接受订阅请求。以后presentity的状态发生变化之后他会发布(PUBLISH)自己的新状态,这个新状态会通知(NOTIFY)给watcher。(注:watcher、presentity等概念严格上来说指网络中的通信实体,这里为了解释方便将他们进行了扩展,也泛指人)

 

随着市场对presence和IM(即时通信)的需求日益增大,各种各样的实现也如雨后春笋般冒了出来。但是目前市场上的大部分实现一般都采用私有协议,相互之间不兼容,呈现功能实现的也不完整。为了对presence和IM规范化,IETF在1998年成立了IMPP(Instant Message and Presence Protocol)工作组,希望设计出健壮、安全和灵活的呈现/即时消息协议。IMPP主要定义必要的协议和数据格式,用来构建一个具有空间接收、发布能力的即时信息系统。现在已经提出了各种不同的协议草案或建议,如:SIMPLE、XMPP、PRIM和APEX等。其中,最有实力的是前两个标准,目前的IM/presence也主要分为两大阵营:SIP/SIMPLE和JABBER/XMPP。本文主要介绍基于SIMPLE的presence。

2.基于SIMPLE协议presence体系结构

SIMPLE规范是在2001年2月由IETF SIMPLE工作组正式提出的,全称为 SIP Instant Messaging and Presence Leveraging Extensions (针对即时消息和呈现业务的利用扩展的会话初始化协议),是SIP协议针对IM/presence的扩展。

 

SIMPLE是目前为止制定的较为完善的一个规范,微软和IBM都致力于在它们的即时通讯系统中实现这个协议。

 

SIMPLE符合RFC2778提出的presence模型,其结构图如下:

 

Figure 1                     presence model

注:上面的实体都是功能实体,与实际实现中的物理实体往往有差别。

 

各实体功能如下:

Ø      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 Service实现为一个Presence Server,Presence User Agent和Presentity组合在一起,Watcher和Watcher User Agent组合在一起,由一个终端来同时支持这两种组合体,这样,一个终端就既能订阅别人的也能发布自己的presence information。

 

3.SIMPLE规范阅读指南
2008-02-20 18:24

 

3.SIMPLE规范阅读指南

IETF的协议规范具有模块化的特点,每一个规范解决一个具体的问题,要构造一个特定功能的系统需要选取适当的规范组合起来共同配合完成功能,SIMPLE的所有规范当然也不例外。IETF针对一个特定的需求往往会先提出一个定义该需求的整体模型,然后由后续的各个规范来详细解决其中的各个子功能(当然,在定义各个子功能的时候也可能会提出针对该类型功能的模型,然后再细化解决)。

 

SIMPLE是SIP的扩展,因此阅读SIMPLE规范之前要对SIP有所了解,SIP入门可以看《SIP揭密》,具体的规范是RFC 3261“SIP: Session Initiation Protocol”。

 

RFC 2778“A Model for Presence and Instant Messaging”定义了一个通用的IM/presence模型,RFC 2779“Instant Messaging / Presence Protocol Requirements”提出IM/presence的需求。

 

对于presence,RFC 3856 “A Presence Event Package for the Session Initiation Protocol (SIP)”整体阐述了presence事件包。

 

每次订阅和发布信息的时候一般都需要鉴权(authentication),比较常见的是采用Digest机制,规范为RFC 2617 “HTTP Authentication: Basic and Digest Access Authentication (for SIP)”。

 

一个典型的presence系统需要处理一下一些事件:

Ø      订阅(SUBSCRIBE)和通知(NOTIFY)presence information:

²       RFC 3265“Session Initiation Protocol (SIP): Specific Event Notification”定义了一套事件通知机制,可应用于presence,作为presence订阅和通知的基本模型,这个机制也适用于下面提到的watcher information。

²       通知presence information的时候需要一种规范的SIP消息体格式以便双方能够识别正确的状态。“draft-ietf-simple-presence-data-model-04”抽象了现实世界中的各种服务、人、设备及其各种信息,并映射到“application/pidf+xml”格式的信息。这种“application/pidf+xml”格式用于SIP消息体中来表示Presentity的各种状态,规范为RFC 3863“Presence Information Data Format (PIDF)”。它有一种扩展叫rpidf,定义了更加丰富的状态信息,草案名是“draft-ietf-simple-rpid-08”。

²       SIMPLE中提出了resource list的概念,在presence中通常用于好友列表,这样订阅(SUBSCRIBE)的时候只需要订阅好友列表对应的URI,Presence Service会返回所有好友的状态信息,不必一个一个好友单独订阅,节省了网络带宽资源(这对移动通信比较现实)也易于管理。“draft-ietf-simple-event-list-07”解释了如何订阅和通知好友列表,订阅好友列表需要的几种新格式也在该草案中有说明或者引用。订阅好友列表还涉及到好友列表的产生、维护等,这在下面说明。

²       订阅一个用户的presence information会涉及到黑白名单,当Watcher处于Presentity的白名单中时,Presence Service可以直接授权Watcher,允许其订阅,不需要再通知Presentity对应的Principal,让其来验证。而相反,处于黑名单的时候,Presence Service直接拒绝Watcher的订阅请求。添加删除黑白名单可用presence rules来实现,具体草案为“draft-ietf-simple-presence-rules-03”。它也是用XCAP协议传送消息的,XCAP见下面。

Ø      订阅(SUBSCRIBE)和通知(NOTIFY)watcher information(下面简称watcherinfo):

²       watcherinfo记录的是订阅一个Presentity的所有Watcher的集合。(注:下文中会出现两种状态,一种是订阅状态,指的是一个Watcher订阅Presentity的presence状态时订阅动作本身的状态,比如“active”表示订阅经授权Presentity的presence状态发生变化时会通知Watcher,“pending”表示收到订阅并被理解,但尚未授权;还有一种就是刚才提到的presence状态,这种状态指的就是一开始说的表征Presentity通信意愿的状态,如“联机”、“忙碌”等)watcherinfo最典型的应用便是通知用户授权,即Presence Service根据本地策略(一般就是黑白名单)不能决定一个订阅是否被授权时会改变Presentity的watcherinfo,从而通知Presentity有人请求订阅其presence状态,让其授权。具体流程见4.3节。

²       RFC 3857“A Watcher Information Event Template-Package for the Session Initiation Protocol (SIP)”介绍了watcherinfo事件模板包的作用、用法等。

²       和presence一样,wathcerinfo也需要一种标准化的格式来表示这种信息,RFC 3858“An Extensible Markup Language (XML) Based Format for Watcher Information”定义了一种叫“application/watcherinfo+xml”的格式来满足这一要求

Ø      发布(PUBLISH)presence状态:

   RFC 3903“Session Initiation Protocol (SIP) Extension for Event State Publication”定义了一种通用的事件状态发布机制,可以应用在presence上发布presence状态信息。

Ø      添加、删除好友以及黑白名单(指的是服务器端存储):

²       这一系列操作都不是用SIP协议来实现的,而是用基于HTTP的XCAP协议来完成这些功能。XCAP用于客户端将跟应用相关的配置数据存储在服务器端,并用HTTP消息结合具体的消息格式来读、写和修改这些数据。草案“draft-ietf-simple-xcap-07”介绍了此协议。

²       XCAP可应用于presence,用来读、写、修改服务器端的好友列表和黑白名单,它们都称为资源列表(resource list)。“draft-ietf-simple-xcap-list-usage-05”定义了资源列表的用法,介绍了两种描述列表的格式:“application/rls-services+xml”和“application/resource-lists+xml”。

 

 

4.典型消息流程

情景设定:

假设本presence系统的域名是“cintel.net.cn”,系统中有一下几个实体:

Ø      Presence Server:系统中的presence服务器。负责接收和处理所辖域内用户的订阅、发布状态请求;通知用户其订阅的状态信息发生改变;处理添加和删除好友;处理添加和删除黑白名单;管理维护所辖域内用户数据等。其SIP-URI为“sip:ps.cintel.net.cn”,FQDN为“ps.cintel.net.cn”

注:这里假设此Presence Server是整个presence系统的authority,也就是说本系统内所有presence用户的数据全由此服务器来管理。本服务器收到一个订阅本系统内用户状态的请求时,不需要向别的服务器进行后端订阅(back-end subscription)。测试环境中这已经满足要求,如果以后再有需求可以增加对跨系统后端订阅的支持。

Ø      A:代表用户A。在网络中是一个终端(可以是软终端或者硬终端),集watcher和presentity实体功能于一身。用于向Presence Server发送订阅(SUBSCRIBE)别的用户状态的请求;自己状态发生变化时向Presence Server发布(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进行了扩展,提供丰富的各种信息,具体见参考[10]。此文档中在PIDF的“status”元素下扩展“im”元素,来表示具体的状态(假设有“联机”、“忙碌”、“离开”和“显示为脱机”四种状态,对应的im元素值分别为“online”、“busy”、“away”和“offline”),前面三种属于“status/basic”值为“open”的情况,后一种属于值为“close”的情况。

 

注:为了便于说明,下面流程中A、B、C三者的关系不是固定的,在具体的情景中有特定的关系

4.1 订阅好友列表

4.1.1情景说明

A拥有且仅拥有B和C两位好友,也就是说A有权订阅B和C的状态信息。终端A启动,向Presence Server发送订阅其好友列表的请求(好友列表URI格式为“sip:username-list@ps.cintel.net.cn”)。假设B一开始处于不在线状态,C至始至终处于“open”状态。Presence Server经过验证将B和C的状态信息通知A。一段时间后B登陆,其状态发生了变化,于是B向Presence Server发布其新状态。Presence Server处理之后将B的新状态通知A,A处理之后会正确显示出B的新状态。在每次订阅超时之前A会重新发送一个订阅请求刷新他的订阅。A退出,向Presence Server发送取消订阅的请求,Presence Server接收并发送最后一次状态通知。

4.1.2 SIP消息流程图

 

Figure 2                        subscribe buddy list

 

4.1.3 消息流说明

1.       A启动,向Presence Server发送订阅其好友列表状态的请求。由于这次订阅的是好友列表,不是单个用户的状态,需要通信双方支持消息体格式:multipart/related、application/rlmi+xml和application/pidf+xml,在Accept头字段中指明A终端支持这三种消息体。此外,好友列表还要求双方支持“eventlist”的扩展,这也要在Supported头字段中指明。此消息中还必须加入头字段Event,表明此次订阅的事件包(event package)类型,在这里其值应该是“presence”。Expires头字段是可选的,用于终端指定一次订阅请求所希望维持的有效时间,单位为秒。如果在订阅请求中没有指定,那么表明终端希望服务器端来指定一个有效时间。

 

   Presence Server收到订阅请求之后,会对A进行验证(Authentication),一般比较常见的是采用Digest机制(见参考[21])。通过验证之后会对请求消息的关键部分进行检查(见参考[22]、[23]),并根据Presence Server所维护的presence rules(定义了每一个用户对别的用户订阅请求的授权情况,通常所说的“黑白名单”就是基于它实现的,见参考[13])对A进行授权。由于我们的情景中已经假设B和C都是A的好友,即A处于B和C定义的presence rules中的“白名单”中,A可以直接从Presence Server处获取B和C的状态(这属于local policy的情形)。脱离这个情景,如果A订阅的好友列表中有用户将其列在黑名单中(即“presence authorization document”中“actions/sub-handing”元素值为“block”,见参考[13]),那么Presence Server将会在后续的NOTIFY请求中通知A针对该用户的订阅状态处于“terminated; reason=rejected”;如果A订阅的好友列表中有用户的订阅状态尚不能确定(即“presence authorization document”中“actions/sub-handing”元素值为“confirm”,见参考[13]或者该document中没有A的信息),那么Presence Server无法在立即返回的NOTIFY中通知A该用户的presence状态,Presence Server会代替A向该用户发起订阅请求,这后续过程会涉及到用户人为干涉验证等,这会在“4.2 订阅单个用户”中详述。

M1消息如下:

SUBSCRIBE sip:A-list@ps.cintel.net.cn SIP/2.0

Via: SIP/2.0/UDP a.cintel.net.cn; branch=z9hG4bKwYb6QREiCL

Max-Forwards: 70

To: < sip:A-list@ps.cintel.net.cn >

From: <sip:A@ps.cintel.net.cn>;tag=ie4hbb8t

Call-ID: cdB34qLToC@a.cintel.net.cn

CSeq: 1 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

2.       由于情景假设,Presence Server可以根据本地策略(local policy)直接获取A好友的presence状态,因此其向A发送“200 OK”,表明此次订阅已经得到验证和授权,订阅操作成功。

 

在此200响应中Presence Server会加入一个Expires头字段,如果前面的SUBSCRIBE中没有指定Expires,那么Presence Server分配一个缺省值,如果已经指定,那么会根据自己的策略选取一个适当的值(见参考[23]),Presence Server可以缩短SUBSCRIBE中指定的时间,但是绝对不能延长这个时间。这里假设Presence Server将此时间缩短为3200秒。此外,由于这个是订阅好友列表的请求,Presence Server还会增加一个Require头字段,值为“eventlist”,表明Presence Server要求终端A支持eventlist扩展。

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

Content-Length: 0

 

 

4.典型消息流程 3
2008-02-20 18:27

3.       根据RFC 3265 [22]的要求,Presence Server在返回一个针对SUBSCRIBE的200 OK响应之后会立即给A发送NOTIFY通知其已经知道的好友的状态。在这个NOTIFY消息中Event和Require头字段同样需要,此外,还要加入一个Subscription-State的头字段(其包含的订阅状态的具体含义见参考[22] 3.2.2章),它包含一个expires参数,指明这次订阅还剩下的有效时间,如果为0,表示服务器端想终止此次订阅。这里由于是立即返回的NOTIFY,因此值为3200。这个NOTIFY请求包含的消息体类型是“multipart/related”,其又包含两中类型的格式:application/rlmi+xml用来描述整个好友列表,application/pidf+xml描述每个好友的具体presence状态信息。在这里,B不在线,因此状态为“offline”,C在线,处于“online”状态。(注pidf可以经扩展支持更加丰富的各种状态信息)

M3消息如下:

NOTIFY 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: 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

Content-ID: <nXYxAE@ 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="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</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</im>

    </status>

    <contact priority="1.0">sip:C@ps.cintel.net.cn</contact>

</tuple>

</presence>

--50UBfW7LSCVLtggUPe5z--

4.典型消息流程 4
2008-02-20 18:27

4.       A收到NOTIFY之后进行处理,将B和C的状态正确显示出来,并返回“200 OK”完成NOTIFY事务。

M4消息如下:

SIP/2.0 200 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头字段(见参考[8])。

M5消息如下:

PUBLISH 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(见参考[8]、[23])。

M6消息如下:

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值