朱春江, 丁革媛, 孫 詠, 賈軍營
(1.中國科學(xué)院研究生院,北京100049;2.中國科學(xué)院沈陽計算技術(shù)研究所網(wǎng)絡(luò)與通信實驗室,遼寧沈陽110171;3.沈陽工業(yè)大學(xué)工程學(xué)院,遼寧沈陽111003)
IM(instantmessaging)的飛速發(fā)展使得它一躍成為互聯(lián)網(wǎng)三大基礎(chǔ)應(yīng)用之首,超過了搜索引擎和電子郵件。在網(wǎng)絡(luò)融合的背景下,IMS客戶端必然會選擇包含IM這項極具商業(yè)價值的業(yè)務(wù)。IMS架構(gòu)中指定SIMPLE(SIP for instant messaging and presence leverage extension)[1]作為IM業(yè)務(wù)的標(biāo)準(zhǔn)規(guī)范。一般認(rèn)為,SIMPLE IM業(yè)務(wù)主要包括,一對一聊天、群組聊天(預(yù)定義群組和臨時群組)、文件傳輸、離線消息和歷史消息存儲等。IMS客戶端中這些業(yè)務(wù)擁有旺盛的需求,特別是群組聊天。目前業(yè)界IMS客戶端支持的業(yè)務(wù)一般都包括一對一聊天、離線消息、歷史消息存儲等,而在最新的標(biāo)準(zhǔn)中定義的群組聊天和文件傳輸,還很少有 IMS客戶端支持。Ericsson的IMS-M客戶端支持臨時群組、文件傳輸,但沒有預(yù)定義群組;法國優(yōu)秀的IMS客戶端Mercuro只支持文件傳輸,不支持群組聊天。因此,市場上還沒有一個IMS客戶端完整地支持群組聊天業(yè)務(wù),群組聊天業(yè)務(wù)是目前IMS客戶端需求最迫切的業(yè)務(wù)。
為了彌補完整的群組聊天業(yè)務(wù)在 IMS客戶端上的空白,本文依據(jù)OMA最新發(fā)布的SIMPLEIM標(biāo)準(zhǔn),研究其中關(guān)于群組聊天業(yè)務(wù)的定義,在IMS客戶端體系架構(gòu)上添加了群組聊天組件,設(shè)計出分別針對預(yù)定義群組和臨時群組的管理器,討論了群組初始化的過程,并實現(xiàn)在SIPHelloIMS客戶端上。經(jīng)測試表明,群組初始化、群組操作、群會話操作、群組消息收發(fā)、事件包訂閱通知等均正確運行,群組聊天業(yè)務(wù)得以成功實現(xiàn)。
SIMPLE和XMPP(extensible messaging and presence protocol)是目前IM的兩個主要標(biāo)準(zhǔn)。SIMPLE IM是SIP協(xié)議針對IM和Presence的擴展。它最早是由IETF SIMPLE工作組于2001年2月提出的。之后,OMA也就SIMPLEIM提出了版本V1.0的一系列規(guī)范,分別定義了業(yè)務(wù)功能架構(gòu)、業(yè)務(wù)需求、技術(shù)規(guī)范。V1.0版本仍是Candidate狀態(tài),OMA和IETF正在對此標(biāo)準(zhǔn)進(jìn)行進(jìn)一步完善。
SIMPLEIM會涉及到OMA定義的另外一些網(wǎng)元,如XDM(XMLdocumentmanagement)[2-3]。OMA 將 IM、Presence、XDM 等功能部件分別定義為一個網(wǎng)元。這些網(wǎng)元擁有各自的一些功能規(guī)范,某些網(wǎng)元需要調(diào)用其他網(wǎng)元的功能。例如,IM和Presence都會使用XDM來管理XML文件。
SIMPLE IM將群組分為預(yù)定義群組(pre-defined group)和臨時群組(Ad-hoc group)。這兩種群組的區(qū)別在于,預(yù)定義群組擁有群組結(jié)構(gòu)文件保存在XDMS,此XML文件的XMLSchema見文獻(xiàn)[4],它保存著此預(yù)定義群組的各項屬性和內(nèi)容,例如群組名稱,顯示名稱,群組成員列表,群組初始化時是否邀請成員,最大邀請人數(shù)以及定義了各個成員屬性(如允許匿名,允許訂閱群會話conference[5]事件包,允許私有信息,允許動態(tài)加入成員,是否接收群廣告,是否是關(guān)鍵用戶,允許別人加入群組等)的規(guī)則集。預(yù)定義群組中“預(yù)定義”3個字的含義應(yīng)該就在于,每一個預(yù)定義群組都擁有一個對應(yīng)的群組結(jié)構(gòu)文件存儲在XDMS上。臨時群組,如同它的名字,是一種臨時創(chuàng)建、臨時銷毀的群組。它的特點是簡單方便。
SIMPLEIM的通信模式有3種:PagerMode,LargeMessage Mode和SessionMode。PagerMode使用SIP的拓展請求MESSAGE方法,信息直接攜帶在消息體中,傳輸過程不需要會話的建立。但是,Pager Mode每個MESSAGE消息只能傳輸最多1300字節(jié)的內(nèi)容,當(dāng)需要傳送大數(shù)據(jù)量時不適用。為了克服此缺點,提出了Large Message Mode。此模式每次需要傳輸信息時就建立起MSRP[6]通道,傳輸完畢后就撤銷MSRP通道。這種方式很好的解決了PagerMode的大消息傳送問題,然而,當(dāng)頻繁發(fā)送消息時,MSRP通道的頻繁建立銷毀就成為了巨大的負(fù)載。Session Mode則在通信雙方之間保持著MSRP通道(IM session),期間可以利用此通道接收發(fā)送消息;MSRP通道的銷毀是由用戶自身或者定時器來觸發(fā)的。
上述3種通信模式都可以用于預(yù)定義群組和臨時群組。但Pager Mode和Large Message Mode只能用于群組消息的發(fā)送和接收;只有Session Mode才有群會話操作。
顧名思義,群組操作和群會話操作分別是針對群組和群會話的。預(yù)定義群組中,群組是由群組結(jié)構(gòu)文件定義的,所以群組操作是指操縱群組結(jié)構(gòu)文件的操作,在任何通信模式下都可以通過XCAP協(xié)議[7]進(jìn)行;群會話操作是指操縱群會話的操作,只有在擁有群會話時才存在,即必須是在Session Mode下進(jìn)行的。臨時群組中,群組的概念更多的是指SessionMode下的群會話,因為PagerMode和LargeMessageMode只能進(jìn)行簡單的群組消息收發(fā),不能進(jìn)行復(fù)雜的群組操作。因此,臨時群組下群組操作就是群會話操作。
群組操作包括,新建群組、加入群組、邀請別人加入群組、退出群組、將成員從群組中刪除掉、銷毀群組等。它們雖然沒有在標(biāo)準(zhǔn)中明確地被提出,但可以從XDM[2-3]和RFC4825[7]中推導(dǎo)出操作的方法。它們都是通過XCAP協(xié)議PUT、GET、DELETE方法操縱IM XDMS上群組結(jié)構(gòu)文件來實現(xiàn)的。
群會話操作包括,發(fā)起群會話、取消發(fā)起的群會話、加入群會話、邀請成員加入群會話、離開群會話、從群會話中刪除成員、結(jié)束群會話等。它們的具體細(xì)節(jié)在標(biāo)準(zhǔn)中定義得比較詳細(xì)。下面簡要介紹客戶端的過程:
(1)發(fā)起群會話:使用INVITE消息,設(shè)置Request-Uri是預(yù)定義群組 Uri或臨時群組 Conference-Factory-Uri。消息攜帶SDP Offer協(xié)商MSRP通道。
(2)取消發(fā)起的群會話:使用CANCEL消息,前提是客戶端還沒有接收到INVITE請求的最終響應(yīng)。
(3)加入群會話:使用INVITE消息,設(shè)置Request-Uri是預(yù)定義群組Uri或臨時群組Session Uri。消息攜帶SDP Offer協(xié)商MSRP通道。
(4)邀請成員加入群會話:使用REFER消息,設(shè)置Request-Uri是Session Uri。Refer-To字段設(shè)置為被邀請成員Uri,邀請多個成員時可以使用RFC4826[8]中定義的Resource-List來攜帶。Method字段是INVITE方法。
(5)離開群會話:使用BYE消息,設(shè)置Request-Uri是SessionUri。
(6)從群會話中刪除成員:使用REFER消息,設(shè)置Request-Uri是Session Uri。Refer-To字段設(shè)置為要刪除的成員Uri,刪除多個成員時可以使用RFC4826[8]中定義的Resource-List來攜帶。Method字段是BYE方法。
(7)結(jié)束群會話:預(yù)定義群組時,群組管理員執(zhí)行銷毀群組的操作,或者群主離開群會話時群組結(jié)構(gòu)文件中Session Release Policy中auto-release字段的值是true[1],此群會話就被結(jié)束了。臨時群組時,群主離開群會話一定會引起該群會話的結(jié)束。
群組聊天業(yè)務(wù)是一項客戶端、服務(wù)器端緊密交互的系統(tǒng)。在此,我們主要關(guān)注客戶端。為了構(gòu)建群組聊天業(yè)務(wù),我們在客戶端的體系架構(gòu)上添加群組聊天組件,如圖1所示。
圖1 客戶端體系架構(gòu)
圖1顯示了“用戶層——UACore——網(wǎng)絡(luò)層”3層體系結(jié)構(gòu)。最上層是用戶層,負(fù)責(zé)接收用戶的操作命令和顯示結(jié)果至用戶。第二層是整個架構(gòu)的核心UACore,這一層相當(dāng)于一個容器,包含著所有核心棧及管理器,如封裝好的信令棧、媒體棧、Presence管理器等。筆者在該層添加了預(yù)定義群組和臨時群組兩個管理器,負(fù)責(zé)一切與群組相關(guān)的操作,管理器的具體設(shè)計見2.2。最底層是網(wǎng)絡(luò)層,負(fù)責(zé)與真實網(wǎng)絡(luò)的交互。
圖2 管理器框架
在圖2中,預(yù)定義群組管理器包括群組部件、群會話部件、XCAP-DIFF[9]事件包訂閱通知部件、Conference[5]事件包訂閱通知部件、預(yù)定義群組消息收發(fā)部件等。而臨時群組管理器只包括群會話部件、Conference事件包訂閱通知部件、臨時群組消息收發(fā)部件等。其中,群組部件通過XCAP協(xié)議與IMXDMS進(jìn)行交互,群會話部件通過SIP協(xié)議(INVITE,BYE,REFER等方法)與IMServer交互;XCAP-DIFF和Conference事件包的訂閱通知部件基于RFC3265的事件通知機制。圖2中事件包訂閱通知接口和群組消息收發(fā)接口在2.3和2.4進(jìn)行介紹。
在圖2中可見,群組消息收發(fā)接口相當(dāng)于一個與IMServer聯(lián)系,匯總、分發(fā)群組消息的接口。發(fā)送消息時,兩個管理器中預(yù)定義群組消息收發(fā)部件和臨時群組收發(fā)部件負(fù)責(zé)從用戶層把要發(fā)送的消息、發(fā)送的目的地等信息收集起來,然后經(jīng)過群組消息收發(fā)接口發(fā)送至IMServer。接收消息時,從IMServer得到消息后,判斷目標(biāo)群組是預(yù)定義群組還是臨時群組,然后把消息傳送至相應(yīng)的部件,在那里傳送至用戶層進(jìn)行顯示和記錄等操作。
根據(jù)通信模式的不同,群組消息收發(fā)接口與IM Server交互的方式也不同。PagerMode下使用的是SIP拓展請求MESSAGE,Session Mode和Large Message Mode都是基于會話的模式,它們使用RFC3862[10]中定義的message/cpim MIME格式進(jìn)行群組消息的收發(fā)。因此,根據(jù)上述兩種不同的情況設(shè)計不同的函數(shù)接口:Pager Mode下使用函數(shù)SendHtmlMessageTo和SendMessageTo分別用于發(fā)送MIME格式為txt/html或txt/plain的消息體,接收MESSAGE消息的回調(diào)則是pfunReceivedPage;Session Mode和 Large Message Mode下使用函數(shù) SendMsrp-DataTo發(fā)送Msrp數(shù)據(jù),接收Msrp數(shù)據(jù)的回調(diào)設(shè)計為pfunOn-MsrpRecvIM。上述5個函數(shù)的具體參數(shù)設(shè)計介紹如下:
(2)發(fā)送Html格式消息函數(shù)SendHtmlMessageTo,參數(shù)列表為unsigned int prof_id,const char*target,const char*txt,int len,int cookie,分別代表ProfileId、發(fā)送目標(biāo)、發(fā)送消息和長度、cookie。
(3)發(fā)送Plain純文本消息函數(shù)SendMessageTo,參數(shù)列表是short nProfId,const char*target,const char*txt,long len,int cookie,分別代表ProfileId、發(fā)送目標(biāo)、發(fā)送消息和長度、cookie。
(4)Msrp數(shù)據(jù)接收回調(diào)pfunOnMsrpRecvIM,參數(shù)列表是long sesId,long strmId,char*buf,int buflen,int contenttype,分別代表Session Id、Stream Id、消息內(nèi)容及長度、MIME格式。
(5)發(fā)送Msrp數(shù)據(jù)函數(shù)SendMsrpDataTo,參數(shù)列表是const char*uri,constchar*buffer,intlen,constintcontenttype,boolbPriority,分別代表目的Uri、消息內(nèi)容及長度、MIME格式、優(yōu)先級。
從圖2中可見,和群組消息收發(fā)接口類似,事件包訂閱通知接口是一個匯總訂閱、分發(fā)通知的接口。訂閱時,預(yù)定義群組管理器中XCAP-DIFF事件包訂閱通知部件把訂閱資源uri,通知方法diff-processing等信息傳送給此接口,此接口再向IM XDMS訂閱。兩個管理器中Conference事件包訂閱通知部件把要訂閱的群會話uri等信息傳送給此接口,之后此接口再統(tǒng)一向IM Server訂閱。通知時,IMXDMS和IMServer等Notifier把Notify消息傳送至此接口,此接口判斷Notify消息的事件包名是XCAP-DIFF還是Conference,訂閱資源屬于預(yù)定義群組還是臨時群組等信息,再把Notify消息傳送至對應(yīng)的部件。
數(shù)碼互動系統(tǒng)是形態(tài)學(xué)實驗教學(xué)的一項重大改革,是一種有效的教學(xué)輔助手段。有利于開展互動化教學(xué)方式和遠(yuǎn)程教學(xué),有利于學(xué)生對形態(tài)學(xué)的理解和學(xué)習(xí)能力水平的提高,經(jīng)過多年實踐,發(fā)現(xiàn)學(xué)生的學(xué)習(xí)成績有很大的提高,形態(tài)學(xué)實驗教學(xué)水平明顯提升。
有了以上分析,筆者設(shè)計了適用于通用事件的訂閱函數(shù)AddSubscription、RefreshSubscription、RemoveSubscription以及事件包通知的回調(diào)pfunOnSubscriptionActive、pfunOnSubscription-Terminated、pfunOnSubscriptionPending等,事件包訂閱通知接口直接使用這些函數(shù)和回調(diào)就可以實現(xiàn)。下面介紹它們的具體參數(shù)設(shè)計:
(1)添加訂閱函數(shù)AddSubscription,參數(shù)列表是constchar*uri,constchar*ev,constintexpire,分別代表訂閱資源、訂閱事件包和過期時間。
(2)刷新訂閱函數(shù)RefreshSubscription,參數(shù)列表是constchar*uri,const char*ev,代表訂閱資源和訂閱事件包。
(3)刪除訂閱函數(shù)RemoveSubscription,參數(shù)列表是constchar*uri,const char*ev,代表訂閱資源和訂閱事件包。
(4)訂閱成功回調(diào)pfunOnSubscriptionActive,參數(shù)列表是int32 prf_id,const char8*uri,const char8*ev,const char8*strContent,int32 len,const char8*mimetype,分別代表 Profile Id、訂閱資源Uri、訂閱事件包、消息體內(nèi)容及長度、MIME類型。
(5)訂閱終止回調(diào)pfunOnSubscriptionTerminated,參數(shù)列表是int32 prf_id,const char8*uri,const char8*ev,const char8*reason,分別代表ProfileId、訂閱資源Uri、訂閱事件包、終止原因。
(6)訂閱掛起回調(diào)pfunOnSubscriptionPending,參數(shù)列表是int32prf_id,constchar8*uri,constchar8*ev,分別代表 ProfileId、訂閱資源Uri、訂閱事件包。
群組初始化是指IMS客戶端用戶登錄成功后的初始化工作,主要是把該用戶所參與的群組加載完畢。群組初始化只針對預(yù)定義群組的初始化,不包括臨時群組的初始化,因為臨時群組是用戶登錄后臨時創(chuàng)建的,用戶剛登錄時是不應(yīng)該存在任何臨時群組的。預(yù)定義群組的加載就是取得群組結(jié)構(gòu)文件,解析后放入內(nèi)存,并進(jìn)行相應(yīng)的界面顯示。筆者認(rèn)為,群組初始化過程存在兩個關(guān)鍵問題,下面具體討論。
2.5.1 用戶參與的群組
初始化時,用戶需要知道他參與了哪些群組。群組結(jié)構(gòu)文件只是說明某個群組的各項屬性,并不包含這個用戶參與了哪些群組的信息。最直觀的想法是,對XDMS中所有用戶樹下的群組結(jié)構(gòu)文件進(jìn)行搜索,把群組成員列表中包含某特定用戶的群組給搜索出來,也就知道了該用戶所參與的所有群組,但顯然搜索過程會引入巨大的時間開銷,不適合在初始化過程中使用。在此,定義了一個XML文件,文件名是BelongGroups.xml,每個用戶都擁有一份自己的BelongGroups.xml存放在XDMS該用戶的用戶樹下,作用是指明該用戶所參與的所有預(yù)定義群組。注意,文件名BelongGroups.xml必須定義為關(guān)鍵字,防止它與同目錄下的群組結(jié)構(gòu)文件的文件名混淆。它的XML Schema如圖3所示。
從圖3的XMLSchema中可以看出,元素belong-groups下有多個one-group子元素,代表該用戶所參與的多個群組;而一個元素 one-group代表一個群組,記錄著這個群組的群組Uri、群組創(chuàng)建者Uri和群組結(jié)構(gòu)文件的文件名。有了這些信息,用戶就可以取得群組結(jié)構(gòu)文件進(jìn)行初始化了。
2.5.2 本地存檔文件
本地需要存檔 BelongGroups.xml和各個群組的群組結(jié)構(gòu)文件。因為IM XDMS出現(xiàn)故障時,用戶無法獲得上述文件就無法初始化,用戶體驗下降。雖然本地存檔的文件不一定是服務(wù)器上最新的版本,但某種程度上給予用戶一定的參考價值。
下一個需要考慮的問題就是,初始化時如何設(shè)計服務(wù)器上遠(yuǎn)程文件或本地文件的加載順序。邏輯上,應(yīng)該是先加載遠(yuǎn)程的BelongGroups.xml,加載成功就繼續(xù)加載各個群組遠(yuǎn)程的群組結(jié)構(gòu)文件,所有群組的群組結(jié)構(gòu)文件都加載成功后初始化就成功結(jié)束了。如果上述過程出現(xiàn)不成功,就加載本地BelongGroups.xml,接著加載本地的群組結(jié)構(gòu)文件。具體流程圖見圖4。
圖3 BelongGroups.xml的XML Schema
圖4 群組初始化加載文件流程
筆者在VC7.1開發(fā)平臺上基于SIPHelloIMSClient上實現(xiàn)了群組聊天業(yè)務(wù)。測試階段測試項目涵蓋了:
(1)群組初始化流程,構(gòu)造條件使程序通過圖4中不同分支分別加載遠(yuǎn)程和本地文件。
(2)各項群組操作,測試這些操作是否導(dǎo)致IMXDMS上對應(yīng)群組結(jié)構(gòu)文件正確地改變;改變后,Notifier是否發(fā)送XCAP-DIFF事件包Notify消息,訂閱了群組結(jié)構(gòu)文件XCAP-DIFF事件包的群組成員是否接收到Notify消息,是否正確地解析消息體并修改本地存檔文件。
(3)各項群會話操作,測試這些操作是否導(dǎo)致群會話狀態(tài)的正確改變;群會話狀態(tài)改變后Notifier是否會發(fā)送Conference事件包的Notify消息,群會話中訂閱了群會話Conference事件包的成員是否接收到此Notify消息,是否正確地解析消息體并修改群會話狀態(tài)。
(4)群組消息收發(fā),測試預(yù)定義群組和臨時群組消息的發(fā)送和接收是否正確。
經(jīng)測試,群組初始化、群組操作、群會話操作、群組消息收發(fā)以及事件包訂閱通知等操作正確運行,擁有一定的穩(wěn)定性。這也驗證了本文SIMPLEIM群組聊天業(yè)務(wù)在IMS客戶端上的設(shè)計是正確有效的。
IMS客戶端市場對群組聊天業(yè)務(wù)需求旺盛,而業(yè)內(nèi)IMS客戶端產(chǎn)品都沒有完整地提供該業(yè)務(wù),這塊空缺造就了群組聊天業(yè)務(wù)的迫切需求。本文根據(jù)最新的SIMPLE IM標(biāo)準(zhǔn),對群組聊天業(yè)務(wù)進(jìn)行詳細(xì)分析,在IMS客戶端體系架構(gòu)上添加了群組聊天組件,設(shè)計出針對預(yù)定義群組和臨時群組的管理器,特別討論了群組初始化流程及其問題,并實現(xiàn)在SIPHello IMSClient上。測試表明群組初始化、群組操作、群會話操作、群組消息收發(fā)以及事件包訂閱通知等均運行成功。下一步工作是繼續(xù)緊跟SIMPLE IM標(biāo)準(zhǔn),對標(biāo)準(zhǔn)中的更新對設(shè)計進(jìn)行進(jìn)一步修改,保持與標(biāo)準(zhǔn)的一致,保證與別的遵循SIMPLEIM標(biāo)準(zhǔn)的IMS客戶端產(chǎn)品之間的互聯(lián)互通。
[1]OMA.Instant messaging using simple[Z].OMA-TS-SIMPLE_IM-V1_0-20080903-C,2008.
[2]OMA.XML document management(XDM)specifi-cation[S].OMA-TS-XDM_Core-V1_1-20080627-A,2008.
[3]OMA.Shared group XDM Specification[Z].OMA-TS-XDM_Shared_Group-V1_0-20090810-C,2008.
[4]OMA.PoC-List Service[S].OMA-SUP-XSD_poc_list-Service-V1_0_2-20090922-A,2009.
[5]Rosenberg J,Schulzrinne H,Levin O.A session initiation protocol(SIP)event package for conference state[S].IETF RFC 4575,2006.
[6]Campbell B,Mahy R,Jennings C.The message session relay protocol(MSRP)[S].IETF RFC 4975,2007.
[7]Rosenberg J.The extensible markup language(XML)configuration Access protocol(XCAP)[S].IETF RFC 4825,2007.
[8]Rosenberg J.Extensible markup language(XML)formats for representing resource lists[S].IETF RFC 4826,2007.
[9]Urpalainen J,Willis D.An extensible markup language(XML)configuration access protocol(XCAP)Diff event package[Z].draft-ietf-sip-xcapevent-08,2009.
[10]Klyne G,Atkins D.Common presence and instant messaging(CPIM):message format[S].IETF RFC 3862,2004.