1、Event Notification的使用背景
在介紹整個(gè)事件推送到場(chǎng)景之前,我們首先大概介紹一下事件推送到使用背景。在1998年, 一些相關(guān)的技術(shù)研究人員就提出了在SIP拓展場(chǎng)景中使用Subscribe和Notify method方式。通過(guò)這種方式可以獲悉對(duì)端的狀態(tài)和通知等。另外一種比較容易理解的使用場(chǎng)景就是中國(guó)用戶經(jīng)常使用的QQ。QQ也使用了類似的工作方式來(lái)實(shí)現(xiàn)QQ對(duì)端用戶的在線狀態(tài),這是我們非常熟悉的環(huán)境。
在很多的SIP通信場(chǎng)景中,本地SIP終端需要獲得對(duì)端的狀態(tài)以便SIP終端進(jìn)行環(huán)境的處理。通過(guò)事件的方式進(jìn)行SIP終端之間的互相不斷互發(fā)跟蹤其分機(jī)狀態(tài)。比較典型的例子就是Presence(在線狀態(tài))的使用。如果本端(watcher)想獲得對(duì)端狀態(tài)的話,本端必須對(duì)其遠(yuǎn)端(publisher)進(jìn)行一個(gè)事件訂閱,這樣,本端就可以實(shí)時(shí)獲取到對(duì)端的狀態(tài)。對(duì)端的狀態(tài)包括了多種形態(tài)和多種數(shù)據(jù)狀態(tài)屬性,本地用戶終端必須要通知對(duì)端所訂閱的事件狀態(tài)。訂閱產(chǎn)生以后,遠(yuǎn)端的狀態(tài)和狀態(tài)數(shù)據(jù)都會(huì)根據(jù)遠(yuǎn)端的環(huán)境變化而隨著產(chǎn)生不同的事件和數(shù)據(jù)。現(xiàn)在問(wèn)題來(lái)了,因?yàn)檫h(yuǎn)端的終端的狀態(tài)是隨時(shí)發(fā)生變化的,同時(shí)會(huì)產(chǎn)生不同的事件,遠(yuǎn)端終端可能無(wú)法獲知本地終端究竟需要那個(gè)事件的數(shù)據(jù),因此本地終端必須對(duì)遠(yuǎn)端事件進(jìn)行特別的訂閱,通過(guò)訂閱具體的事件來(lái)獲取相應(yīng)的返回?cái)?shù)據(jù),否則遠(yuǎn)端會(huì)發(fā)送返回錯(cuò)誤。通過(guò)訂閱具體的事件ID就不會(huì)產(chǎn)生錯(cuò)誤的返回消息,遠(yuǎn)端可以及時(shí)推送相應(yīng)的事件和事件類型。
在具體的訂閱流程中,可能產(chǎn)生不同的數(shù)據(jù),不同時(shí)間攜帶了不同的數(shù)據(jù)格式(XML格式),通過(guò)豐富的數(shù)據(jù)格式來(lái)表示當(dāng)前的終端狀態(tài)。終端之間的訂閱實(shí)現(xiàn)方式可以支持點(diǎn)對(duì)點(diǎn)的訂閱和通過(guò)服務(wù)器處理的訂閱方式來(lái)處理。我們會(huì)在下面的章節(jié)中做進(jìn)一步的介紹。
2、SIP Event Notification的工作原理
介紹了一些基本的背景知識(shí)以后,我們這里重點(diǎn)介紹一下事件提示的基本工作原理。Event Notification本身可以使用在很多的系統(tǒng)中,SIP技術(shù)對(duì)其進(jìn)行了擴(kuò)展支持。通過(guò)Subscribe和Notify的方式,它可以應(yīng)用在以下幾個(gè)方面的語(yǔ)音場(chǎng)景中:
- Presence/IM 即時(shí)消息系統(tǒng)環(huán)境
- 緊急狀態(tài)提示
- SIP的會(huì)議控制
- 其他應(yīng)用
前面我們已經(jīng)討論了關(guān)于事件的類型,如果不知道事件類型的話,本地終端沒(méi)有辦法獲取到對(duì)端具體的數(shù)據(jù)數(shù)據(jù)。因此,我們需要首先介紹一下event的類型和其需要遵守的相關(guān)的兩個(gè)規(guī)則。
需要遵守SIP協(xié)議規(guī)則,因?yàn)镋vent Notification通過(guò)SIP來(lái)進(jìn)行協(xié)商,因此,它必須遵守SIP消息的處理流程。
需要遵守事件類型以及響應(yīng)數(shù)據(jù)屬性的規(guī)則,在攜帶的數(shù)據(jù)中包括了事件名稱和數(shù)據(jù)的其他屬性數(shù)值,因此它必須遵守相關(guān)的XML語(yǔ)法規(guī)范和數(shù)據(jù)規(guī)范。
在實(shí)際的應(yīng)用場(chǎng)景中,事實(shí)上事件類型包括了很多類型。我們比較常見(jiàn)的類型包括:Presence,Reg等。RFC6665對(duì)具體的事件類型的定義有非常詳細(xì)的介紹。我們這里羅列了一個(gè)匯總表方便讀者了解各種事件類型。
各種事件類型都有其相應(yīng)的SIP header,pay load,數(shù)據(jù)結(jié)構(gòu)和屬性參數(shù)。讀者如果想進(jìn)一步了解這些具體的規(guī)范的話,可以自己研究。因?yàn)槠膯?wèn)題,我們僅介紹幾個(gè)比較常用的事件和數(shù)據(jù)類型。
在Event Notification的介紹中,筆者建議讀者首先需要了解到是RFC3842規(guī)范,此規(guī)范具體定義了message summary和MWI數(shù)據(jù)包的結(jié)構(gòu)。通過(guò)此規(guī)范可以基本掌握了事件訂閱,數(shù)據(jù)類型等必要的基礎(chǔ)知識(shí)。以下示例是一個(gè)RFC3842的規(guī)范示例,本端SIP分機(jī)對(duì)遠(yuǎn)端SIP分機(jī)在一定時(shí)間內(nèi)進(jìn)行一個(gè)訂閱請(qǐng)求處理。雙方通過(guò)發(fā)送SIP消息,數(shù)據(jù)和確認(rèn)同步來(lái)獲取對(duì)端的狀態(tài)信息。
如果對(duì)端狀態(tài)消息更新以后,本地可以收到回復(fù)信息和相關(guān)的數(shù)據(jù)內(nèi)容。具體內(nèi)容屬性根據(jù)不同的數(shù)據(jù)不同而產(chǎn)生不同的數(shù)據(jù)(以上示例中A13的消息內(nèi)容)。
3、關(guān)于Notification的相關(guān)RFC規(guī)范
當(dāng)我們討論Event Notification時(shí),我們討論了多個(gè)rfc規(guī)范。這些規(guī)范是SIP協(xié)議的一些擴(kuò)展協(xié)議,需要結(jié)合RFC3261來(lái)進(jìn)一步學(xué)習(xí)。為了能夠?qū)W⒂谖覀兘?jīng)常使用的幾個(gè)場(chǎng)景進(jìn)行討論,我們這里僅討論幾個(gè)經(jīng)常使用的規(guī)范,方便讀者可以進(jìn)行進(jìn)一步學(xué)習(xí),它們包括:
RFC6665, 它是SIP的拓展協(xié)議,提供了一個(gè)拓展框架,SIP節(jié)點(diǎn)可請(qǐng)求一個(gè)notification來(lái)表示某些事件已發(fā)生。
RFC3903,它是一個(gè)SIP拓展協(xié)議,在SIP event中支持pblish event狀態(tài)。
RFC3842,它提供對(duì)SIP Event數(shù)據(jù)包描述信息,支持對(duì)感興趣的用戶傳輸消息等待狀態(tài)和消息summaries。
以上三種規(guī)范是我們經(jīng)常使用的規(guī)范,讀者在使用過(guò)程中需要根據(jù)其語(yǔ)法結(jié)構(gòu)和傳輸方式進(jìn)行,結(jié)合其具體的請(qǐng)求方式來(lái)進(jìn)行分析。
4、SIP Reg 中的事件包分析討論
在前面的討論中我們?cè)?jīng)提到了reg事件包,現(xiàn)在我們根據(jù)其規(guī)范定義來(lái)具體討論一下SIP注冊(cè)的event 數(shù)據(jù)包的語(yǔ)法和示例場(chǎng)景。通過(guò)SIP注冊(cè)的支持,Event 數(shù)據(jù)包可以創(chuàng)建,修改和刪除注冊(cè)packages。很多情況下,SIP終端需要不斷更新其狀態(tài)來(lái)實(shí)現(xiàn)第三方的定義需求。在SIP注冊(cè)中,這個(gè)數(shù)據(jù)包的名稱是reg,它出現(xiàn)在Event頭中,支持SUBSCRIBE和NOTIFY請(qǐng)求中。reg支持了事件包的各種屬性和其狀態(tài),具體的狀態(tài)如下:
三種狀態(tài)分別代表:
- Init: 沒(méi)有注冊(cè)狀態(tài)
- Active:已注冊(cè)狀態(tài)
- Terminated: 已不再注冊(cè)狀態(tài)
在消息體中,此規(guī)范定義了消息的數(shù)據(jù)格式和數(shù)據(jù)包名稱,其規(guī)范內(nèi)容如下:
All subscribers and notifiers MUST support the "application/reginfo+xml" format
https://tools.ietf.org/html/rfc3680
其示例如下:
消息內(nèi)容如下:
- SUBSCRIBE sip:joe@example.com SIP/2.0
- Via: SIP/2.0/UDP app.example.com;branch=z9hG4bKnashds7
- From: sip:app.example.com;tag=123aa9
- To: sip:joe@example.com
- Call-ID: 9987@app.example.com
- CSeq: 9887 SUBSCRIBE
- Contact: sip:app.example.com
- Event: reg
- Max-Forwards: 70
- Accept: application/reginfo+xml
返回的Notify消息內(nèi)容:
- NOTIFY sip:app.example.com SIP/2.0
- Via: SIP/2.0/UDP server19.example.com;branch=z9hG4bKnasaii
- From: sip:joe@example.com;tag=xyzygg
- To: sip:app.example.com;tag=123aa9
- Call-ID: 9987@app.example.com
- CSeq: 1288 NOTIFY
- Contact: sip:server19.example.com
- Event: reg
- Max-Forwards: 70
- Content-Type: application/reginfo+xml
- Content-Length: …
- <?xml version="1.0"?>
- <reginfo xmlns="urn:ietf:params:xml:ns:reginfo"
- version="0" state="full">
- <registration aor="sip:joe@example.com" id="a7" state="init" />
- </reginfo>
讀者注意這里的event(reg)和state,因?yàn)槭纠械腟IP終端還沒(méi)有注冊(cè),因此它的狀態(tài)是init的狀態(tài)。一段時(shí)間后,分機(jī)注冊(cè)以后,NOTIFY的數(shù)據(jù)包發(fā)生了變化,分機(jī)注冊(cè)成功,其狀態(tài)信息也隨之發(fā)生了變化,狀態(tài)修改為“active”狀態(tài):
- NOTIFY sip:app.example.com SIP/2.0
- Via: SIP/2.0/UDP server19.example.com;branch=z9hG4bKnasaij
- From: sip:joe@example.com;tag=xyzygg
- To: sip:app.example.com;tag=123aa9
- Call-ID: 9987@app.example.com
- CSeq: 1289 NOTIFY
- Contact: sip:server19.example.com
- Event: reg
- Max-Forwards: 70
- Content-Type: application/reginfo+xml
- Content-Length: …
- <?xml version="1.0"?>
- <reginfo xmlns="urn:ietf:params:xml:ns:reginfo"
- version="1" state="partial">
- <registration aor="sip:joe@example.com" id="a7" state="active">
- <contact id="76" state="active" event="registered"
- duration-registered="0">
- <uri>sip:joe@pc34.example.com</uri>
- </contact>
- </registration>
- </reginfo>
在此示例中,筆者介紹了關(guān)于reg的結(jié)果比較關(guān)鍵的知識(shí)點(diǎn)。關(guān)于reg的規(guī)范,讀者可以查閱rfc3680進(jìn)行進(jìn)一步的學(xué)習(xí)。
5、如何使用Subscribe,Notify和Publish
在前面的章節(jié)的討論中,我們大部分的討論在peer-to-peer的環(huán)境中進(jìn)行討論。一端是訂閱端,另外一方發(fā)送Notify端。但是,這種使用方式僅僅限于一些小并發(fā)的SIP用戶場(chǎng)景中,使用的方式可能也僅限于呼叫狀態(tài)的一些基本的狀態(tài)功能。相等于點(diǎn)對(duì)點(diǎn)的處理方式,大家可能已經(jīng)猜到,那就是服務(wù)器處理或中央處理方式的事件發(fā)布方式。服務(wù)器端可以支持多種事件類型,根據(jù)不同的用戶訂閱方式提供不同的事件類型。其用戶包括(Presence User Agent,PUA)和Subscribers(watchers)。服務(wù)區(qū)作為一個(gè)Event State Compositor (ESC)。ESC記錄不同的事件類型和其狀態(tài)屬性參數(shù)。訂閱方定時(shí)對(duì)服務(wù)器訂閱數(shù)據(jù)進(jìn)行提取更新。RFC3903中的關(guān)于ESC的處理示例流程圖:
ESC服務(wù)器通過(guò)設(shè)置定時(shí)器和超時(shí)設(shè)置,不斷刷新其數(shù)據(jù)庫(kù)數(shù)據(jù)。如果PUA狀態(tài)發(fā)生了變化,就會(huì)對(duì)ESC發(fā)送數(shù)據(jù)。然后,ESC對(duì)訂閱方發(fā)生狀態(tài)更新數(shù)據(jù)。
所有的數(shù)據(jù)交換都必須通過(guò)服務(wù)器來(lái)進(jìn)行處理,不同于點(diǎn)對(duì)點(diǎn)的使用方式,ESC的處理方式就可以實(shí)現(xiàn)多種方式的訂閱和大并發(fā)呼叫使用。
6、Subscribe,Notify和Publish的工作機(jī)制
上面的討論中,我們了解了ESC的大概工作原理,這里,我們?cè)俅胃鶕?jù)具體的交換數(shù)據(jù)做一些討論。為了讓PUA支持?jǐn)?shù)據(jù)發(fā)送,首先,PUA需要對(duì)ESC服務(wù)器發(fā)送一個(gè)Pubish的請(qǐng)求,請(qǐng)求中標(biāo)識(shí)了event的類型和其數(shù)據(jù)屬性狀態(tài)。
如果其他的SIP終端對(duì)ESC發(fā)送了其他的事件包數(shù)據(jù),也可以通過(guò)ESC服務(wù)器進(jìn)行更新,這里的XML數(shù)據(jù)中的狀態(tài)也發(fā)生了變化。訂閱方就可以提取到某個(gè)特定PUA的數(shù)據(jù)更新?tīng)顟B(tài)。
7、Event Notification對(duì)SIP服務(wù)器的性能影響
通過(guò)以上介紹,我們基本了解了Event Notification的處理機(jī)制,數(shù)據(jù)格式和傳輸方式。大家通過(guò)這些介紹可以知道,事實(shí)上,服務(wù)器和終端之間傳輸?shù)臄?shù)據(jù)量是非常大的。這取決于幾個(gè)主要的要素:SIP終端數(shù)量,定時(shí)器設(shè)置,訂閱數(shù)量和消息體構(gòu)成等。這些要素設(shè)置可能會(huì)影響服務(wù)器的性能以及其穩(wěn)定性。具體的表現(xiàn)為數(shù)據(jù)傳輸延遲,狀態(tài)更新不準(zhǔn)確,消息丟失等問(wèn)題。Georgios Panagiotou 曾經(jīng)對(duì)其設(shè)計(jì)架構(gòu)發(fā)表了一篇論文,讀者可以查閱來(lái)討論。Erkki Harjula在很早以前的論文中也對(duì)部署方式帶來(lái)的服務(wù)器的影響進(jìn)行了研究,可以作為讀者學(xué)習(xí)的資料。
當(dāng)然,因?yàn)榛ヂ?lián)網(wǎng)技術(shù)的發(fā)展和網(wǎng)絡(luò)帶寬的增加,一些問(wèn)題可能逐步得到了解決。針對(duì)peer-to-peer或者ESC場(chǎng)景,如果SIP端通過(guò)一定的優(yōu)化,也許可能會(huì)降低一些數(shù)據(jù)的傳輸和頻率,例如設(shè)置一些數(shù)據(jù)過(guò)濾機(jī)制,定時(shí)器時(shí)間進(jìn)行調(diào)整等方法。
8、總結(jié)
在本文章中,筆者根據(jù)SIP應(yīng)用的場(chǎng)景首先對(duì)SIP 事件消息推送做了比較簡(jiǎn)單的背景知識(shí)介紹,通過(guò)介紹,讓讀者了解了Event Notification的作用。然后,我們介紹了基本的知識(shí)和其相關(guān)的協(xié)議規(guī)范。筆者通過(guò)reg event package的示例說(shuō)明了事件創(chuàng)建,更新和數(shù)據(jù)屬性的構(gòu)成。筆者通過(guò)討論點(diǎn)對(duì)點(diǎn)部署方式和服務(wù)器部署方式討論了Subscribe, Notify和Publish的工作機(jī)制,并且針對(duì)服務(wù)器的性能做了進(jìn)一步的分析和優(yōu)化討論。
以上這些討論具有一定的局限性,沒(méi)有涉及每一個(gè)eventpackage的使用場(chǎng)景,所以難免會(huì)出現(xiàn)一些錯(cuò)誤的表述,因此,讀者最好根據(jù)自己的實(shí)際場(chǎng)景和相關(guān)的規(guī)范來(lái)做更專業(yè)的分析,這里,僅是拋磚引玉。
參考資料:
http://www.mediateam.oulu.fi/publications/pdf/814.pdf
https://people.kth.se/~devlic/publications/SNCNW2009.pdf
https://tools.ietf.org/html/rfc3903
https://tools.ietf.org/html/rfc6665
FreeSBC
關(guān)注微信公眾號(hào):asterisk-cn,獲得有價(jià)值的Asterisk行業(yè)分享
Asterisk freepbx 中文官方論壇:http://bbs.freepbx.cn/forum.php
Asterisk freepbx技術(shù)文檔: www.freepbx.org.cn
融合通信商業(yè)解決方案,協(xié)同解決方案首選產(chǎn)品:www.hiastar.com
Asterisk/FreePBX中國(guó)合作伙伴,官方qq技術(shù)分享群(3000千人):589995817