SIP 探析

摘要

  會話發起協議(Session Initiation Protocol,SIP)是一種信令協議,它對於通信業有着重要的意義。本文從技術上對SIP進行了一般性的介紹,並說明了SIP如何爲通信解決方案提供重要支持。

簡介

  我曾經構想過一種軟件,它可以“浮於”應用程序之上,提供輔助作用。這不是一個啞的“幫助”系統,而是一個活動的技術支持代理,可以在Internet上進行討論。那時曾有人告訴我,“現有的工具、庫、協議或帶寬實現不了這樣的要求!”

  時代已經不同了!

  許多人家中已經擁有基於DSL、光纖和其他技術的寬帶網絡。存在大量高質量的工具和庫,無論是商業的還是開源的。標準驅動應用。現在是時候來實現上述創新思路了。

瞭解SIP

  首先,我將向您介紹SIP,也就是會話發起協議。SIP是一種輕量級的可擴展請求/響應協議,用於在兩個端點之間開始通信會話。這聽起來是不是很熟悉?SIP在概念上源自於HTTP和SMTP,但是它的目的卻不同。可以把SIP消息與CB(民用波段)隱語10-code和Q-signal進行比較。

用於管理CB呼叫的隱語
圖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說明了這次呼叫:

一次典型的SIP呼叫

圖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 SDP (JSR 141)
  • Java Media Framework for RTP (J2SE可選包,並非JAIN的)

  如果您希望開發一個客戶端應用程序,就需要一個客戶端SIP引擎或者“堆棧”。在這裏可以找到一個優秀的開源Java SIP堆棧。它還支持SDP。如果不想自己開發SIP電話,您可以使用這個

結束語

  本文簡要介紹了SIP、它的使用場景,以及一些SIP語法。我們還了解了各種與SIP相關的Java技術。儘管本文不夠詳盡,我還是希望它能夠激發您的興趣,並促使您開始使用它。SIP的時代已經到來,現在使用它可以實現很多很酷的想法。
在本系列文章的第2部分中,我將說明如何使用SIP Servlet API編寫一個聊天室應用程序。

參考資料

  原文出處:http://dev2dev.bea.com/pub/a/2005/09/introduction-sip-part-1.html

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章