摘要
會話發起協議(Session Initiation Protocol,SIP)是一種信令協議,它對於通信業有着重要的意義。本文從技術上對SIP進行了一般性的介紹,並說明了SIP如何爲通信解決方案提供重要支持。
簡介
我曾經構想過一種軟件,它可以“浮於”應用程序之上,提供輔助作用。這不是一個啞的“幫助”系統,而是一個活動的技術支持代理,可以在Internet上進行討論。那時曾有人告訴我,“現有的工具、庫、協議或帶寬實現不了這樣的要求!”
時代已經不同了!
許多人家中已經擁有基於DSL、光纖和其他技術的寬帶網絡。存在大量高質量的工具和庫,無論是商業的還是開源的。標準驅動應用。現在是時候來實現上述創新思路了。
瞭解SIP
首先,我將向您介紹SIP,也就是會話發起協議。SIP是一種輕量級的可擴展請求/響應協議,用於在兩個端點之間開始通信會話。這聽起來是不是很熟悉?SIP在概念上源自於HTTP和SMTP,但是它的目的卻不同。可以把SIP消息與CB(民用波段)隱語10-code和Q-signal進行比較。
圖1.用於管理CB呼叫的隱語
在這個例子中,真正的消息包含在專用的呼叫協商消息中。
SIP是IETF於1999年提出的,在2002年進行了修訂。RFC 3261對它進行了描述。本文中有關SIP的信息就選自RFC。對SIP存在很多擴展,這些擴展中的很多都能在SIP-related RFCs and drafts清單中找到。
SIP有哪些優點呢?通常情況下,兩個端點使用它來協商一次“呼叫”。這裏的協商包括介質(文本、語音等)、傳輸(通常是RTP、Real Time Protocol)和編碼(codec)。一旦協商成功,兩個端點就會使用選中的方法相互交談——這就與SIP無關了。“呼叫”完成之後,SIP用於指示斷開連接。因此,SIP最好用作一種信令機制。SIP及其擴展還提供一些相關功能,比如即時消息傳遞、註冊和到場。
SIP術語中的端點叫做用戶代理。它可以是“軟件電話”、即時消息收發器、IP電話,甚至是手機。服務器用戶代理提供集中式的服務,比如登記員、代理或應用服務器。
聽起來SIP非常簡單,而且它也確實簡單。這種簡單性對於協議的穩定很重要,而且它也沒有降低協議的有用性,所以該協議得到了廣泛的應用。
例如,考慮一下HTTP。協議本身的定義很少。但是使用它的方式多不勝數。SIP也是可以擴展的。存在大量針對SIP的擴展,它們涵蓋了很多應用。現在,我們進一步來考察SIP,並分析它爲什麼會如此重要。
SIP的重要性
有人說,SIP對於通信,就像HTTP對於Web一樣。
SIP對通信業產生了巨大的影響。從事蜂窩技術的公司已經決定爲了未來的應用,對SIP進行標準化。VoIP (Voice over IP)供應商、Internet電話和即時消息傳遞應用程序(例如,Microsoft MSN Messenger)都準備基於SIP進行標準化。
目前已經存在一些信令協議和P2P技術。這就引發了一個問題:SIP相對於這些協議和技術有何優勢?SIP具有以下的明顯優點:
- 穩定性。該協議已經使用了多年,現在十分穩定。
- 速度。基於UDP的小型協議效率特別高。
- 靈活性。這個基於文本的協議十分容易擴展。
- 安全性。它提供像加密(SSL、S/MIME)和身份驗證這樣的功能。對SIP的擴展還提供其他安全性功能。
- 標準化。隨着整個通信行業都在向SIP靠攏,SIP已經訊速成爲一種標準。其他技術可能具有SIP所沒有的優勢,但是它們沒有得到全球範圍內的採用。
這意味着,如果您想讓您的應用程序與其他工具、設備和服務器進行互操作,SIP是最佳選擇。供應商對互操作性是很關注的,會定期開會對其產品進行測試。這些會議稱爲SIPit for SIP Interoperability Tests(以前叫做Bakeoff,是Pillsbury提出更改的)。
剖析SIP呼叫
現在,讓我們更深入地瞭解這門技術。SIP通常基於UDP進行傳輸,但是SIP工具必須同時支持TCP。一條SIP消息由兩部分組成:
- 信封(envelope),以頭字段的形式描述一個請求或請求的結果(響應)。
- 有效負載(payload),即內容(可選),包含有關請求的數據。
信封是文本格式,但是內容可以是文本,也可以是二進制格式。
例如,讓我們具體分析一次典型的SIP呼叫。在這個場景中,用戶A想呼叫用戶B。圖2說明了這次呼叫:
圖2. 一次典型的SIP呼叫
下面對所有的消息進行了解釋:
1. User Agent A發送一個SIP請求INVITE給User Agent B,表達User A想跟User B進行談話的願望。這個請求包含語音流協議的細節。payload中使用會話描述協議(Session Description Protocol,SDP)就是爲此目的。SDP消息包含一個清單,其內容爲User A支持的所有介質編碼。(這些編碼使用RTP進行傳輸。) | INVITE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 10.20.30.40:5060 From: UserA <sip:[email protected]>;tag=589304 To: UserB <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Contact: <sip:[email protected]> Content-Type: application/sdp Content-Length: 141 v=0 o=UserA 2890844526 2890844526 IN IP4 10.20.30.40 s=Session SDP c=IN IP4 10.20.30.40 t=3034423619 0 m=audio 49170 RTP/AVP 0 a=rtpmap:0 PCMU/8000 |
2. User Agent B讀取該請求,然後告訴User Agent A它已經收到請求。 | SIP/2.0 100 Trying From: UserA <sip:[email protected]>;tag=589304 To: UserB <sip:[email protected]> Call-ID: [email protected] CSeq: 1 INVITE Content-Length: 0 |
3.當電話響鈴時,User Agent B發送臨時消息(響鈴)給User Agent A,這樣它就不會超時和放棄。 | SIP/2.0 180 Ringing From: UserA <sip:[email protected]>;tag=589304 To: UserB <sip:[email protected]>;tag=314159 Call-ID: [email protected] CSeq: 1 INVITE Content Length: 0 |
4.最終,User B決定接受呼叫。此時,User Agent B發送一個OK響應給User Agent A。在響應的payload中,還有另一條SDP消息。它包含一組兩個用戶代理都支持的介質編碼。此時,雙方正式處於呼叫中。使用200類型的響應可以接受所有類型的SIP請求。 | SIP/2.0 200 OK From: UserA <sip:[email protected]>;tag=589304 To: UserB <sip:[email protected]>;tag=314159 Call-ID: [email protected] CSeq: 1 INVITE Contact: <sip:[email protected]> Content-Type: application/sdp Content-Length: 140 v=0 o=UserB 2890844527 2890844527 IN IP4 10.20.30.41 s=Session SDP c=IN IP4 10.20.30.41 t=3034423619 0 m=audio 3456 RTP/AVP 0 a=rtpmap:0 PCMU/8000 |
5. User Agent A最後使用一條ACK消息進行確認。對於這種請求類型來說,沒有重試和響應消息,即使消息丟失。ACK只在INVITE消息中使用。 | ACK sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 10.20.30.41:5060 Route: <sip:[email protected]> From: UserA <sip:[email protected]>;tag=589304 To: UserB <sip:[email protected]>;tag=314159 Call-ID: [email protected] CSeq: 1 ACK Content-Length: 0 |
6..兩個用戶代理現在使用最後一條SDP消息中選定的方法進行連接。 | RTP使用PCMU/8000編碼對在端口49170 & 3456上雙向傳輸的音頻數據進行打包。 |
7.在通信會話結束時,其中一個用戶掛斷。此時,這個用戶的用戶代理髮送一個新的請求BYE。這條消息可以由任一方發送。 | BYE sip:[email protected] SIP/2.0 Via: SIP/2.0/UDP 10.20.30.41:5060 To: UserB <sip:[email protected]>;tag=314159 From: UserA <sip:[email protected]>;tag=589304 Call-ID: [email protected] CSeq: 1 BYE Content-Length: 0 |
8.另一用戶的用戶代理接受該請求,然後使用一條OK消息作爲應答。呼叫連接至此斷開。 | SIP/2.0 200 OK To: UserB <sip:[email protected]>;tag=314159 From: UserA <sip:[email protected]>;tag=589304 Call-ID: [email protected] CSeq: 1 BYE Content-Length: 0 |
SIP消息的第一行包含消息的類型和所使用的SIP版本(2.0)。在請求中,這一行還包含一個叫做SIP URI的地址。這代表消息的目的地。
這個例子說明了如何使用請求消息INVITE、ACK和BYE,以及200 OK響應消息。SIP中還存在許多其他消息。下面給出一些請求:
消息 | 用法 |
---|---|
INVITE | 呼叫一個用戶代理,傳送一次呼叫。 |
ACK | 確認呼叫。 |
BYE | 終止呼叫。 |
CANCEL | 終止還未OK的呼叫。 |
REGISTER | 提供一項註冊服務,帶有一個聯繫地址和可以用來代替的別名。例如,在前面的例子中,地址sip:[email protected]就是sip:[email protected]的別名。然後,註冊服務器example.com就可以把呼叫轉發給地址10.20.30.40。 |
OPTIONS | 詢問一個用戶代理的“能力”(例如,該用戶代理能夠識別的消息和編碼)。 |
現在給出一些經常使用的響應消息:
消息 | 用法 |
---|---|
100 Trying | 消息已收到,但是最終用戶代理尚未進行處理。請等待。 |
180 Ringing | 最終用戶代理已經收到消息,正在提示用戶。請等待。 |
200 OK | 最終用戶已經接受消息。 |
301 Moved Permanently & 302 Moved Temporarily | 用戶代理的地址已經改變,新的永久或臨時地址位於Contact字段中。 |
400 Bad Request | 普通錯誤消息。客戶端不能識別消息。 |
401 Unauthorized & 407 Proxy Authentication Required | 請使用證書重試。 |
404 Not Found | 要聯繫的用戶不存在或尚未註冊。 |
408 Request Timeout | 另一方沒有響應。這意味着SIP消息永遠不會OK。所有重試都將被丟棄。這並不意味着電話響太長時間(電話可以永遠響鈴)。 |
消息使用類似的頭字段類型。下面給出其中的一些:
頭字段 | 用法 |
---|---|
From | SIP請求的發送者。 |
To | SIP請求的接受者。這通常與SIP URI相同(可以是一個“別名”或一個實際地址)。 |
Contact | 用戶代理的實際地址。 |
Call-ID | 這並不是呼叫者的電話號碼。它惟一地代表兩個用戶代理之間的完整呼叫或對話。所有相關的SIP消息都使用同一個Call-ID。例如,當一個用戶代理收到一條BYE消息,根據Call-ID,它就知道要掛斷哪次呼叫。 |
CSeq | 消息的順序編號。這在一次對話或一個Call-ID中是惟一的。這用於區別新的消息和“重試消息”。當一條初始消息沒有及時OK時,重試就會進行,並會定時發送。 |
Content-Type | 消息內payload的MIME類型。 |
Content-Length | payload的大小,以字節爲單位。信封和payload之間由一空行隔開。 |
還有一些與消息路由選擇功能相關的頭字段,如:Via、Route和Record-Route。許多頭字段提供像Accept、User-Agent和Supported這樣的功能。其他頭字段則提供像Authorization、Privacy和WWW-Authenticate這樣的安全性功能。還有很多其他的頭字段存在。此外,這些字段中許多都有縮寫語法(比如,From = f,To = t,等等)。
SIP的其他功能
使用SIP及其擴展可以實現很多應用:
- VoIP
- 視頻會議
- 針對文本和數據的即時消息傳遞,比如MSN Instant Messenger
- 註冊(我在線!)
- 到場(我的夥伴在不在?)
- Click-to-talk(點擊通話,即點擊這裏便可與一個技術支持代理交談)
- 應答機器/互動式語音應答(Interactive Voice Response,IVR)系統(“請輸入您的密碼。請記錄您的姓名。英文請按1,西班牙語請按2…”)
- 網絡遊戲,比如Quake和一些手機遊戲(甚至基於語音和IM)
- 基於手機的應用程序
- 移動電子商務
基本上,如果是兩個端點之間進行通信,SIP就能完成。
但是,關於活動的Web技術支持代理的想法又如何呢?現在我們能否使用SIP來實現它?我們能否使用Java來實現它?乾脆點說,可以。
Java中的SIP
我經常使用SIP。我可以負責任地說,Java爲SIP提供了絕佳的支持。Java技術的一個分支把與開發SIP應用程序相關的許多細節抽象出來,這對於SIP開發人員大有幫助。下面這些技術大部分位於JAIN (Java APIs for Integrated Networks)工作組中。
- JAIN SIP API (JSR 32)
- SIP Servlet API (JSR 116)
- JAIN SIP Lite (JSR 125)
- SIP API for J2ME (JSR 180)
- JAIN SIMPLE Presence (JSR 164)
- JAIN SIMPLE Instant Messaging (JSR 165)
其他相關技術有:
- JAIN SDP (JSR 141)
- Java Media Framework for RTP (J2SE可選包,並非JAIN的)
如果您希望開發一個客戶端應用程序,就需要一個客戶端SIP引擎或者“堆棧”。在這裏可以找到一個優秀的開源Java SIP堆棧。它還支持SDP。如果不想自己開發SIP電話,您可以使用這個。
結束語
本文簡要介紹了SIP、它的使用場景,以及一些SIP語法。我們還了解了各種與SIP相關的Java技術。儘管本文不夠詳盡,我還是希望它能夠激發您的興趣,並促使您開始使用它。SIP的時代已經到來,現在使用它可以實現很多很酷的想法。
在本系列文章的第2部分中,我將說明如何使用SIP Servlet API編寫一個聊天室應用程序。
參考資料
- SIP Forum——SIP工作組的社區站點
- SIP Center——另一個廣受歡迎的社區站點
- RFC 3261——SIP規範
- SIP的相關RFC和草案
- 開源JAIN SIP堆棧
- 開源SIP軟件電話
原文出處:http://dev2dev.bea.com/pub/a/2005/09/introduction-sip-part-1.html