會話發起協定(Session Initiation Protocol,SIP)是一種信令協定,廣泛應用於建立、修改與終端兩個端點之間的多媒體會話。無論是雙方通話、多方會議、VoIP 語音通話、即時通訊、好友列表管理,還是網路會議,SIP 都是這些遠程通訊應用的核心底層技術。JSR 116 定義的 SIP Servlet API 提供了伺服器端介面,描述了針對 SIP 元件與服務的容器規格。SIP Servlet 在 SIP 容器中運行,類似於 HTTP Servlet,但專門處理 SIP 協定請求。
結合 Java EE 技術,SIP Servlet 能為企業應用程式帶來豐富的媒體互動能力。JSR 289(SIP Servlet v1.1)進一步更新了 API,定義了標準的應用程式程式設計模型,使 SIP Servlet 能與 Java EE 元件無縫整合,成為下一代電信服務的關鍵技術。
理解 SIP 最直觀的方式是透過應用場景。假設用戶 A 想呼叫用戶 B,雙方透過用戶代理(如軟體電話或 VoIP 手機)通訊。建立呼叫的基本流程如下:

圖 1. 建立呼叫的步驟
SIP 透過定義特定的請求方法(REGISTER、INVITE、ACK、CANCEL、BYE、OPTIONS)、響應代碼(1xx~6xx)以及標準化的 Header 欄位,實現了上述流程的標準化。該協定已由 IETF 依據 RFC 3261 標準化,並被 3GPP 採納為標準信令協定,成為 IP 多媒體子系統(IMS)架構的核心元素。
雖然 SIP 與 HTTP 同屬應用層協定,但 SIP 不使用 HTTP 作為底層協定,而是基於 TCP、UDP 或 SCTP 傳輸。兩者有許多相似之處:均為文字基礎、人類可讀、採用「請求-響應」機制、擁有方法與狀態碼。關鍵差異在於:SIP 的請求-響應是非同步的(請求不需立即獲得對應響應),且 SIP 為對等協定——用戶代理既可作為客戶端也可作為伺服器,而 HTTP 中角色固定。
SDP 用於描述多媒體會話中的媒體格式與類型。SIP 將 SDP 作為訊息主體承載,促進用戶代理間的能力交換,例如指定支援的編解碼器、傳輸協定(如 RTP)等。
SIP 訊息包含三大部分:

圖 2. SIP 訊息的組成部分
SIP Servlet 模型基於傳統 Servlet 模型,使 SIP 程式開發更貼近 Java EE。Servlet 容器負責管理生命週期、資源(JNDI、JDBC)與網路連線。SIP Servlet 針對各種 SIP 方法定義對應的處理方法,例如 doInvite() 處理 INVITE 請求,類比 HTTP Servlet 的 doPost()。
JSR 116 定義了 SIP Servlet API 1.0,規範了程式設計模型 API、容器職責、與 HTTP Servlet 及 Java EE 元件的互動方式。後續修訂為 JSR 289 (SIP Servlet v1.1)。
SIP 的請求-響應模型與 HTTP 類似,但一個 SIP 請求可能產生多個響應,或無對稱響應。SipServletRequest 與 SipServletResponse 分別封裝請求與響應,共同實作 SipServletMessage 介面,提供通用方法。

Servlet Context 適用於 SIP Servlet,可與 HTTP Servlet 共享上下文屬性。部署描述符採用 sip.xml(XML Schema 定義),描述 SIP Servlet、對應規則、資源與環境屬性。SIP 應用程式打包結構同 Web 應用,使用 .sar (SIP Archive) 或 .war 格式。
為支援同一應用同時使用 HTTP 與 SIP Servlet,規格定義了 ConvergedContext,提供共享的 Servlet Context、資源與 JNDI 命名空間視圖。同時包含兩類 Servlet 的應用稱為融合應用,除 sip.xml 外還包含 web.xml。JSR 289 進一步擴展至企業應用層級,形成融合企業應用程式。
SipSession 代表基於 SIP 的協定會話,對應 HTTP 的 HttpSession。SipApplicationSession 為應用層級的父會話,統管 HTTP 與 SIP 會話,適用於融合應用場景。
JSR 289 引入 Java EE 5 風格的 Annotation,簡化配置:
@SipServlet:標記 SIP Servlet 類別@SipApplication:定義 SIP 應用程式邏輯群組,可替代部署描述符@SipListener:註冊 SIP 事件監聽器@SipApplicationKey:定義將請求關聯至現有 SipApplicationSession 的鍵值策略SIP Servlet 容器可為獨立型(僅支援 SIP)或融合型(支援 HTTP + SIP)。企業級應用通常需要融合容器。Project Sailfin 基於 GlassFish 應用伺服器,由 Sun 與 Ericsson 主導開發,提供 SIP Servlet 容器的開源實作,支援 SIP Servlet API 1.0 並規劃支援 1.1 規範。
CallSetup 為 Sailfin 附帶範例,展示 SIP Servlet 與 HTTP Servlet 協作提供 VoIP 服務。核心採用背靠背用戶代理(B2BUA)模式:B2BUA 分別向雙方發起呼叫,再將兩路媒體串接,完成端到端連線。
Registration.java:用戶註冊資料 POJORegistrarServlet:處理 REGISTER 請求,持久化用戶資料至 Java DBRegistrationBrowserServlet:HTTP Servlet,提供 Web 介面選擇呼叫雙方SipCallSetupServlet:HTTP Servlet,發起 INVITE 給被叫方 (UserB)B2BCallServlet:SIP Servlet,處理響應、交換 SDP、建立雙向呼叫web.xml、sip.xml、sun-web.xml、persistence.xml:部署與持久化配置
圖 4. CallSetup 的執行順序
doRegister() 解析請求中的 Contact Header,將用戶位址持久化至資料庫(使用 JPA EntityManager 與 JTA UserTransaction),成功回 200 OK,失敗回 500。
從資料庫查詢註冊清單,生成 HTML 表單提交至 SipCallSetupServlet,由用戶選擇主叫與被叫。
取得用戶選擇的雙方位址,透過 SipFactory 建立 SipApplicationSession、Address 物件,構造 INVITE 請求發送給 UserB,並設定 SipSession 的 Handler 為 "b2b"(即 B2BCallServlet),以便處理後續響應。
doResponse() 處理 INVITE 的響應:
SipSession 互相關聯(OTHER_SESSION 屬性),雙方 Handler 均設為 "b2b"sip.xml 定義兩個 Servlet(registrar、b2b)與對應規則:registrar 處理特定域名下的 REGISTER/INVITE/OPTIONS/MESSAGE;b2b 負責呼叫控制邏輯。persistence.xml 設定 JTA 資料源 jdbc/__default 供註冊資料持久化。
依照 Sailfin 官方安裝與部署指南操作,成功後可在兩個 Softphone 客戶端間建立 VoIP 呼叫,雙方電話將響鈴互通。
本文介紹了 SIP 協定基礎、SIP Servlet 程式模型、融合應用架構與關鍵 API 概念,並透過 CallSetup 範例展示如何利用 SIP Servlet 與 HTTP Servlet 協作實作 VoIP 服務。Project Sailfin 提供了基於 GlassFish 的開源 SIP 容器實作,為企業整合語音通訊功能提供了可行路徑。