馮玖江,袁星勇,王建兵,陳 量,羅明陽
(重慶金美通信有限責任公司,重慶 400030)
Presence也作Presence Information,該技術是伴隨即時消息通信業務一起發展而出現的,用來傳遞用戶的通信能力和通信意愿,通信能力表明當前用戶是否支持話音、是否支持視頻業務或者是否支持文本消息等;通信意愿表明當前用戶是否愿意通信,如“離開”狀態,那么其他用戶只能向其發送離線消息。呈現是一種業務能力,可以為其它平臺提供業務服務,如PoC服務平臺、即時消息業務平臺。
SIMPLE標準依據RFC2778和RFC2779規范制定了Presence服務的模型[1]如圖1所示。

圖1 呈現模型
Presence Service:接收、存儲和分發呈現信息,包括處理訂閱請求,處理發布請求、和授權規則的執行,既可以是一個實體服務器,也可以是presentity和watcher之間的直接通信;
Presentity:呈現信息源,用于發布呈現信息給呈現服務器。
Watcher:觀察者,是呈現信息的訂閱者和觀察者,接收處理來自呈現服務器的呈現信息,可以是一個具體的終端用戶,也可以是一些網絡設備。
Presence User Agent和Wathcer User Agent是用戶向Presentity和Watcher提供信息的操作接口。
在具體開發實現中,常把Presence Service實現為一個實體服務器,將Presence User Agent和Presentity組合在一起,將Watcher和Watcher User Agent組合在一起,由一個終端來同時支持這兩種組合體,這樣,一個終端就既能訂閱別人的狀態也能發布自己的呈現信息。
點對點業務包括3部分實體:狀態觀察者(Watcher)、狀態發布者(Presentity)和呈現服務器(Presence Server);點對點業務模型如圖1所示。
點對點模型的信令流程如圖2所示,watcher需要向每一個presentity發布訂閱消息SUBSCRIBE,但如果每個觀察者需要訂閱很多人的狀態信息,那就需要發送很多的SUBSCRIBE消息,這大大增加了網絡的負擔。
watcher在接收到NOTIFY消息后,將內容解析后,顯示到圖形界面。

圖2 點對點業務信令流程
基于資源列表的模型需要XCAP服務器、資源列表服務器、呈現服務器、訂閱者和呈現信息發布者組成,其組成模型如圖3所示。

圖3 資源列表業務模型
XCAP服務器上主要存儲resource-lists文件、rls-service文件以及其它授權策略文檔,用戶或者其他服務器通過XCAP(XML Configuration Manage Protocol)協議進行訪問和修改。
資源列表服務器主要接收來自終端訂閱者的列表訂閱請求SUBSCRIBE,根據資源列表信息代替終端發起虛擬訂閱,收集整合呈現信息,并通知給訂閱終端。呈現服務器主要處理呈現發布者的PUBLISH信息和來自資源列表服務器的訂閱信息SUBSCRIBE。
XCAP協議[2]是一種基于HTTP的文本協議,用于讀寫用戶配置文檔的通信協議,允許用戶使用GET、PUT、DELETE方法對資源文檔進行讀寫、刪除數據等操作,還可以對群組文件,授權策略文件進行修改。
終端訂閱者登錄以后通過XCAP協議從XCAP服務器上獲取rls-service文檔和resource-lists文檔,rls-service訂閱了資源列表服務器上相關的服務,resource-lists則定義了每個服務資源的URI;終端訂閱者根據resource-lists文檔信息,向文檔中描述的URI資源發起訂閱。資源列表服務器和呈現服務器也能從XCAP服上獲取或者修改相應的授權策略文件。

圖4 呈現信息訂閱流程
圖4的呈現訂閱流程解釋如下。
步驟1:終端訂閱者Joe登錄后向資源列表服務發起對sip:joe-list@ps.cintel.net.cn發起列表訂閱,訂閱信息為了區別點對點訂閱,應該增加消息頭Supported: eventlist和接受的文檔類型Accept:application/pidf+xml,application/rlmi+xml 和 Accept:multipart/related三種類型。
步驟2:列表資源服務器通過授權策略文件驗證后接收本次訂閱,然后資源列表根據sip:joe-list@ps.cintel.net.cn指向的資源發現A-list包含Alice和Bob兩個用戶,且這兩個用戶分布在不同的服務域,此時資源列表服務器分別向呈現服務器A和呈現服務器B發起虛擬訂閱。
步驟3:Alice和Bob用戶上線后分別向自己的域服務器發送PUBLISH消息,將自己的狀態發送到呈現服務器A和呈現服務器B,PUBLISH消息中需要 Expires:3600和 Event:presence[3-4],呈現服務器收到新狀態后,返回一個200OK給Alice和Bob,并在響應中帶一個SIP-ETag頭域,用來標識和驗證下一次的PUBLISH信息。
步驟4:呈現服務器A和呈現服務器B把收集到的呈現信息以NOTIFY消息通知給資源列表服務器。
步驟5:資源服務將來自呈現服務器A和B的呈現信息整理后,形成一個整體呈現信息體,然后發送NOTIFY消息通知給Joe訂閱者,資源列表服務器采用增量通知方式,只將狀態有變化的用戶推送給訂閱者。
呈現服務器內部按功能劃分成獨立的模塊,如圖5所示,模塊間松耦合聯系,使用UDP報文相互通信完成模塊信息交換。

圖5 呈現服務器架構
(1)狀態發布處理模塊
狀態發布處理模塊主要記錄用戶發布的呈現信息,當用戶刷新或更新用戶信息時更新服務器記錄;當用戶取消發布時,刪除服務器該用戶記錄等功能。該模塊是其他用戶獲得該用戶狀態的基礎。
(2)訂閱請求處理模塊
訂閱處理模塊在用戶發送訂閱時,記錄該用戶訂閱信息,當用戶刷新訂閱時更新訂閱信息;當用戶取消訂閱時,刪除該用戶訂閱關系。訂閱是用戶接收其他用戶呈現信息的基礎。
(3)定時通知模塊
用戶狀態有更新時,定時通知模塊聚合有狀態更新的成員,發送給非初始訂閱用戶;如果是初始訂閱用戶,模塊會聚合所有成員狀態發送到初始訂閱用戶。
服務器內部對PUBLISH的處理流程如圖6所示,Sip-if-match[5]區分是否是刷新發布,收到發布消息后,按內存中是否存在該呈現信息做不同處理。

圖6 服務器對PUBLISH的處理
服務器收到用戶的訂閱請求SUBSCRIBE后處理流程如圖7所示,首先解析消息根據to_tag頭域判斷該請求是原始請求還是刷新請求,如果是原始請求則需要從資源列表中下載獲取rls-service文檔,并對文檔中的URI描述的資源發起虛擬訂閱;如果是刷新訂閱,則構造通知消息NOTIFY發送給訂閱者。

圖7 服務器對SUBSCRIBE的處理流程
定時模塊會被定時器和初始訂閱觸發,定時器觸發后只把狀態更新的信息發送給訂閱用戶,如果是初始訂閱的話,則會把當前所有狀態信息全部通知給訂閱用戶,其處理流程如圖8所示。

圖8 定時通知模塊處理流程
測試平臺采用kmailio開源代碼進行二次開發實現呈現業務,該工程包含了XCAP服務、RLS服務和呈現服務,三個服務部署在同一臺服務器上,內部通過UDP報文進行信令交互;融合通信終端采用開源工程eXosip和osip作為二次開發的協議棧,能實現訂閱SUBSCRIBE、PUBLISH消息功能,能解析NOTIFY消息。
測試用例中使用了三個用戶Alice、Bob和Joe,Joe登錄后獲取好友列表joe-list,列表包含Alice和Bob兩個用戶,然后訂閱joe-list獲取Alice和Bob的狀態,Alice和Bob登錄后向呈現服務器發送自己的狀態。
終端發送的SUBSCRIBE消息格式[5]:


本文設計通過開源代碼kamailio進行二次開發,實現了基于呈現列表的訂閱服務功能,通過系統性能測試驗證,能并發處理1 000條/秒的訂閱消息,通過自研融合通信終端進行功能測試,能實現在線、離線,會議中、登陸位置等信息、自定義狀態等狀態信息發布。