ヘッダをスキップ
Oracle® WebLogic Communication Services 開発者ガイド
11g リリース 1 (11.1.1)
B55506-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

1 SIP サーブレット アプリケーションの開発の概要

この章では、SIP サーブレット アプリケーションの開発について説明します。以下の節で構成されています。

1.1 SIP サーブレットとは

SIP Servlet API は、JCP (Java Community Process) の JSR289 として標準化されています。


注意 :

このドキュメントでは、「SIP Servlet」という用語で API を表し、この API を使って作成されたアプリケーションを「SIP サーブレット」と称しています。

Java Servlet はサーバサイド アプリケーションの構築に使用されます。HttpServlet は Servlet のサブクラスで、Web アプリケーションの作成に使用されます。SIP Servlet は SIP 固有の機能が追加された汎用サーブレット API と定義されます。

図 1-1 Servlet API と SIP Servlet API

サーブレット API
「図 1-1 Servlet API と SIP Servlet API」の説明

SIP Servlet は HTTP Servlet とよく似ているので、HTTP サーブレットの開発者はこのプログラミング モデルにすぐに慣れるでしょう。HTTP Servlet で定義されているサービス レベルと SIP Servlet で定義されているサービス レベルはよく似ているので、HTTP と SIP の両方をサポートするアプリケーションを設計するのは簡単です。コード リスト 1-1 は単純な SIP サーブレットの例です。

例 1-1 SimpleSIPServlet.java

package oracle.example.simple;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.sip.*;

public class SimpleSIPServlet extends SipServlet {
    protected void doMessage(SipServletRequest req)
       throws ServletException, IOException
    {
       SipServletResponse res = req.createResponse(200);
       res.send();
    }
}

上の例は、SIP MESSAGE リクエストに対して 200 OK 応答を返す単純な SIP サーブレットを示しています。このリストからわかるように、SIP Servlet と HTTP Servlet には次のような多くの共通点があります。

  1. サーブレットは API が提供する基本クラスを継承する必要があります。HTTP サーブレットは HttpServlet を継承し、SIP サーブレットは SipServlet を継承する必要があります。

  2. メソッド doXxx をオーバーライドして実装する必要があります。HTTP サーブレットには GET/POST メソッドに対応する doGet/doPost メソッドがあります。同様に、SIP サーブレットにはメソッド名 (上の例では MESSAGE メソッド) に対応する doXxx メソッドがあります。アプリケーション開発者は必要なメソッドをオーバーライドして実装します。

  3. SIP Servlet のライフサイクルおよび管理メソッド (init、destroy) は HTTP Servlet とまったく同じです。セッションおよび属性の操作も同じです。

  4. 上の例では表示されませんが、web.xml に対応する SIP サーブレットの sip.xml という名前のデプロイメント記述子があります。アプリケーション開発者とサービス マネージャは、複数の SIP サーブレットを使用してアプリケーションをコンフィグレーションするためにこのファイルを編集することができます。

ただし、SIP サーブレットと HTTP サーブレットの間には相違点もいくつかあります。重要な違いの 1 つにプロトコルによるものがあります。次の節では、こうした相違点と SIP サーブレットの特徴について説明します。

1.2 HTTP サーブレットとの相違点

この節では、SIP サーブレットと HTTP サーブレットの違いについて説明します。

1.2.1 複数の応答

例 1-1 でお気づきかもしれませんが、doMessage メソッドには引数が 1 つしかありません。HTTP では、トランザクションは 1 対のリクエストと応答から成っているので、doXxx メソッドの引数でリクエスト (HttpServletRequest) と応答 (HttpServletResponse) を指定します。アプリケーションはリクエストを実行するために、そこからパラメータなどの情報を取り出し、結果を応答の本体で返します。

protected void doGet(HttpServletRequest req, HttpServletResponse res)
   throws ServletException, IOException

SIP では、1 つのリクエストに対して複数の応答を返すこともできます。

図 1-2 SIP におけるリクエストと応答の例

SIP におけるリクエストと応答
「図 1-2 SIP におけるリクエストと応答の例」の説明

上の図は INVITE リクエストへの応答例を示しています。この例では、サーバが 1 つの INVITE リクエストに対して 3 つの応答 (100、180、200) を返しています。SIP サーブレットでこのようなシーケンスを実装するには、doXxx メソッドでリクエストのみを指定し、アプリケーションがオーバーライドしたメソッドで必要な応答を生成して返します。

現在、SIP Servlet では以下の doXxx メソッドが定義されています。

protected void doInvite(SipServletRequest req);
protected void doAck(SipServletRequest req);
protected void doOptions(SipServletRequest req);
protected void doBye(SipServletRequest req);
protected void doCancel(SipServletRequest req);
protected void doSubscribe(SipServletRequest req);
protected void doNotify(SipServletRequest req);
protected void doMessage(SipServletRequest req);
protected void doInfo(SipServletRequest req);
protected void doPrack(SipServletRequest req);

1.2.2 応答の受信

SIP の重要な特徴の 1 つとして、クライアントとサーバが固定されないという点があります。HTTP の場合、Web ブラウザは常に HTTP リクエストを送信し、HTTP 応答を受信します。HTTP リクエストを受信し、HTTP 応答を送信することはありません。しかし、SIP では各端末がクライアントとサーバの両方の機能を持っている必要があります。

たとえば 2 つの SIP 電話で考えると、両方とも相手に電話をかけたり通話を切ったりできる必要があります。

図 1-3 SIP におけるクライアントとサーバの関係

SIP におけるクライアントとサーバ
「図 1-3 SIP におけるクライアントとサーバの関係」の説明

上の例は、呼び出しまたは切断を行う端末がクライアントとして動作していることを示しています。SIP では、クライアントとサーバの役割を 1 回のダイアログの中で逆転することができます。このクライアント機能を UAC (User Agent Client)、サーバ機能を UAS (User Agent Server)、端末を UA (User Agent) と呼びます。SIP Servlet では応答を受信するためのメソッドも定義されています。

protected void doProvisionalResponse(SipServletResponse res);
protected void doSuccessResponse(SipServletResponse res);
protected void doRedirectResponse(SipServletResponse res);
protected void doErrorResponse(SipServletResponse res);

これらの doXxx 応答メソッドはリクエストのメソッド名ではありません。次のように応答のタイプによって名前が付けられています。

  • doProvisionalResponse - 暫定応答 (1xx 応答) の受信時に呼び出されるメソッド

  • doSuccessResponse - 成功応答の受信時に呼び出されるメソッド

  • doRedirectResponse - リダイレクト応答の受信時に呼び出されるメソッド

  • doErrorResponse - エラー応答 (4xx、5xx、6xx 応答) の受信時に呼び出されるメソッド

応答を受信するためのメソッドが存在するということは、SIP Servlet ではリクエストと応答がそれぞれ別々のスレッドでアプリケーションに送られることを意味しています。アプリケーションは SIP メッセージの関連を明示的に管理する必要があります。リクエストと応答がそれぞれ独立していると、処理のプロセスはいくらか複雑になりますが、より柔軟なプロセスを記述することが可能になります。

SIP Servlet を使用すると、アプリケーションでリクエストを明示的に作成することもできます。これらの機能を使用することで、SIP サーブレットはサーバ (UAS) としてリクエストを待つだけでなく、クライアント (UAC) としてリクエストを送信することができます。

1.2.3 プロキシ機能

別の HTTP プロトコルとは異なるもう 1 つの機能は「フォーク」です。フォークは 1 つのリクエストを複数のサーバに同時に (または連続的に) プロキシする処理で、複数の端末 (オペレータ) が 1 つの電話番号に (コール センターなどで) 関連付けられている場合に使用されます。

図 1-4 プロキシ フォーク

プロキシ フォーク
「図 1-4 プロキシ フォーク」の説明

SIP Servlet には、プロキシ機能を持つアプリケーションのために SIP リクエストをプロキシするユーティリティが備わっています。

1.2.4 メッセージ ボディ

下の図からわかるように、SIP メッセージの構造は HTTP と同じです。

図 1-5 SIP メッセージの例

SIP メッセージの例
「図 1-5 SIP メッセージの例」の説明

HTTP は本質的に HTML ファイルと画像を転送するためのプロトコルです。転送するコンテンツはメッセージ ボディに格納されます。HTTP Servlet では、大量のコンテンツを送受信できるようにするストリーム操作ベースの API が定義されています。

1.2.4.1 Servlet リクエスト

ServletInputStream getInputStream()
BufferedReader     getReader()

1.2.4.2 Servlet 応答

ServletOutputStream getOutputStream()
PrintWriter         getWriter()
int  getBufferSize()
void setBufferSize(int size)
void resetBuffer()
void flushBuffer()

それに対して SIP では、メッセージ ボディに少量のコンテンツしか格納されません。なぜなら、SIP はリアルタイムのコミュニケーションを想定しているからです。したがって、上記のメソッドは互換性を維持するためだけに存在し、機能は無効になっています。

SIP においてボディに格納されるコンテンツとしては以下のものがあります。

  • SDP (Session Description Protocol) - 端末間で使用されるマルチメディア セッションを定義するためのプロトコル。このプロトコルは RFC2373 で定義されています。

  • プレゼンス情報 - CPIM で定義されているプレゼンス情報を記述するメッセージ。

  • IM メッセージ - IM (インスタント メッセージ) ボディ。ユーザ入力メッセージはメッセージ ボディに格納されます。

メッセージ ボディはサイズが小さいので、これをストリーミングで処理するとオーバーヘッドが増加します。SIP Servlet は API を再定義して、次のようにメッセージをメモリ上で操作するようにしています。

1.2.4.3 SipServletMessage

void   setContent(Object content, String contentType)
Object getContent()
byte[] getRawContent()

1.2.5 サーブレット コンテナの役割

以下の節では、SIP サーブレット コンテナとして OWLCS が提供する主要な機能について説明します。

  • アプリケーション管理 - サーブレット コンテキストによるアプリケーション管理、サーブレットのライフサイクル管理、デプロイメント記述子によるアプリケーション初期化などの機能について説明します。

  • SIP メッセージング - 着信した SIP メッセージを解析して適切な SIP サーブレットに渡す、SIP サーブレットによって作成されたメッセージを適切な UAS に送信する、SIP ヘッダ フィールドを自動的に設定するといった機能について説明します。

  • ユーティリティ機能 - セッション、ファクトリ、プロキシなど、SIP サーブレットで使用できる機能について説明します。

1.2.5.1 アプリケーション管理

HTTP サーブレット コンテナと同様、SIP サーブレット コンテナもサーブレット コンテキストによってアプリケーションを管理します (図 1-6 を参照)。サーブレット コンテキスト (アプリケーション) は通常は WAR 形式で保管され、各アプリケーション サーバにデプロイされます。


注意 :

アプリケーション サーバにデプロイする方法は、それぞれの製品によって異なります。実際のアプリケーション サーバのドキュメントを参照してください。

図 1-6 サーブレット コンテナとサーブレット コンテキスト

サーブレットと SIP コンテキスト
「図 1-6 サーブレット コンテナとサーブレット コンテキスト」の説明

コンバージド SIP/Web アプリケーションのサーブレット コンテキストには、SIP サーブレット、HTTP サーブレット、および JSP を含めることができます。

OWLCS では、プラットフォームとしてお使いのアプリケーション サーバと同じ方法でアプリケーションをデプロイすることができます。ただし、SIP サーブレットを含むアプリケーションをデプロイする場合は、SIP サーブレットで定義された SIP 固有のデプロイメント記述子 (sip.xml) が必要です。一般的なコンバージド SIP/Web アプリケーションのファイル構造を次の表に示します。

表 1-1 アプリケーションのファイル構造の例

ファイル

説明

WEB-INF/

コンバージド SIP/Web アプリケーションのコンフィグレーション ファイルと実行ファイルをこのディレクトリに配置します。このディレクトリ内のファイルを Web 上で直接参照することはできません (サーブレットではできます)。

WEB-INF/web.xml

Web アプリケーションの Java EE 標準コンフィグレーション ファイル。

WEB-INF/sip.xml

SIP アプリケーションの SIP Servlet 定義のコンフィグレーション ファイル。

WEB-INF/classes/

コンパイル済みのクラス ファイルをこのディレクトリに保存します。HTTP サーブレットと SIP サーブレットの両方を保存することができます。

WEB-INF/lib/

JAR ファイルとしてアーカイブされたクラス ファイルをこのディレクトリに保存します。HTTP サーブレットと SIP サーブレットの両方を保存することができます。

*.jsp, *.jpg

JSP などの Web アプリケーションを構成するファイルを Java EE と同じ方法でデプロイすることができます。


sip.xml ファイルで指定する情報は web.xml のものと似ていますが、<servlet-mapping> 設定は HTTP サーブレットとは異なります。HTTP では、URL のファイル名部分に関連するサーブレットを指定します。しかし、SIP にはファイル名という概念がありません。SIP リクエストのヘッダ フィールドまたは URI を使ってフィルタ条件を設定します。次の例では、「register」という SIP サーブレットがすべての REGISTER メソッドに割り当てられています。

例 1-2 sip.xml のフィルタ条件の例

 <servlet-mapping>
   <servlet-name>registrar</servlet-name>
   <pattern>
     <equal>
       <var>request.method</var>
       <value>REGISTER</value>
     </equal>
   </pattern>
 </servlet-mapping>

デプロイされた後、サーブレット コンテキストのライフサイクルはサーブレット コンテナによって保守されます。サーブレット コンテキストの起動/停止は通常はサーバの起動/停止時に行われますが、システム管理者がサーブレット コンテキストの起動、停止、再ロードを明示的に行うこともできます。

1.2.5.2 SIP メッセージング

SIP サーブレット コンテナが提供する SIP メッセージング機能は以下のタイプに分類されます。

  • 受信した SIP メッセージを解析する

  • 解析したメッセージを適切な SIP サーブレットに渡す

  • SIP サーブレット生成のメッセージを適切な UA に送信する

  • 応答 (「100 Trying」など) を自動的に生成する

  • SIP ヘッダ フィールドを自動的に管理する

SIP サーブレットが処理するすべての SIP メッセージは、SipServletRequest オブジェクトまたは SipServletResponse オブジェクトとして表現されます。受信したメッセージはパーサによって解析されてから、これらのオブジェクトのいずれかに変換され、SIP サーブレット コンテナに送られます。

SIP サーブレット コンテナは以下の 3 種類の SIP メッセージを受信します。いずれであるかにより、ターゲット サーブレットが決められます。

  • 最初の SIP リクエスト - SIP サーブレット コンテナは、どの SIP セッションにも属していないリクエストを受け取ると、前述した sip.xml ファイル内のフィルタ条件を使ってターゲットの SIP サーブレットを決定します。コンテナは初期リクエストを受け取ったときに新しい SIP セッションを作成するので、その時点以降に受け取った SIP リクエストは後続のリクエストと見なされます。


    注意 :

    フィルタ処理は慎重に行ってください。OWLCS では、受信した SIP メッセージが複数の SIP サーブレットに合致する場合に、いずれか 1 つの SIP サーブレットに渡されます。

    リクエスト パラメータなどの追加の基準を使用して、サーブレットにリクエストを転送することができます。


  • 後続の SIP リクエスト - SIP サーブレット コンテナは、いずれかの SIP セッションに属するリクエストを受け取ると、そのリクエストをそのセッションに関連付けられた SIP サーブレットに渡します。リクエストがセッションに属するかどうかは、ダイアログ ID を使って判別されます。

    SIP サーブレットはメッセージを処理するたびに、コンテナが呼 ID をロックします。SIP サーブレットは、後続のリクエストを受け取るときに同じ呼 ID の以前のリクエストを処理している場合、SIP サーブレット コンテナは後続のリクエストをキューイングします。キューイングされたメッセージは、サーブレットが最初のメッセージの処理を終了し、SIP サーブレット コンテナに制御を返した後にのみ処理されます。

    この並行処理制御は、1 つのコンテナとクラスタ化された環境の両方で保証されています。アプリケーション開発者は、どのような特定の呼 ID に対しても 1 つのメッセージだけが所定の時間に処理されることを理解して、アプリケーションのコードを作成することができます。

  • 受信した応答が SIP サーブレットがプロキシしたリクエストに対するものであれば、その SIP セッションは特定されているため、応答は自動的に同じサーブレットに渡されます。SIP サーブレットがそれ自身のリクエストを送信する場合は、最初に SIP セッションで応答を受け取るサーブレットを指定する必要があります。たとえば、リクエストを送信する SIP サーブレットで応答も受信する場合は、SIP セッションで次のハンドラ設定を指定する必要があります。

    SipServletRequest req = getSipFactory().createRequest(appSession, ...);
    req.getSession().setHandler(getServletName());
    

    SIP で「セッション」というと、通常は RTP/RTSP によるリアルタイム セッションを意味します。それに対して HTTP Servlet では、「セッション」が複数の HTTP トランザクションを関連付ける方法を意味します。このドキュメントでは、セッション関連の用語を次のように定義します。

表 1-2 セッション関連の用語

リアルタイム セッション

RTP/RTSP によって確立されたリアルタイム セッション。

HTTP セッション

HTTP Servlet によって定義されたセッション。複数の HTTP トランザクションを関連付ける方法。

SIP セッション

HTTP セッションと同じ概念を SIP で実装する方法。SIP (RFC3261) には似通った概念として「ダイアログ」がありますが、ライフサイクルと生成の条件が異なるため、このドキュメントではこれを別の用語として扱います。

アプリケーション セッション

複数のプロトコルおよびダイアログを使って複数の HTTP セッションおよび SIP セッションを関連付けるアプリケーションのための方法。「AP セッション」ともいいます。


OWLCS は以下に示す応答プロセスと再送信プロセスを自動的に実行します。

  • 「100 Trying」の送信 - WebLogic Communications Server は INVITE リクエストを受信すると、自動的に「100 Trying」を作成して送信します。

  • CANCEL への応答 - WebLogic Communications Server は CANCEL リクエストを受信すると、そのリクエストが有効なら次のプロセスを実行します。

    1. CANCEL リクエストに対して 200 応答を送信します。

    2. キャンセル対象の INVITE リクエストに対して 487 応答を送信します。

    3. SIP サーブレット上で doCancel メソッドを呼び出します。これにより、アプリケーションは doCancel メソッド内でプロセスを中止することができ、明示的に応答を返す必要がなくなります。

  • INVITE へのエラー応答に対して ACK を送信 - SIP サーブレットによって送信された INVITE に対して 4xx、5xx、または 6xx 応答が返されたとき、WebLogic Communications Server は自動的に ACK を作成して送信します。なぜなら、ACK は SIP シーケンスでのみ必要であり、SIP サーブレットはこれを必要としないからです。

    SIP サーブレットが INVITE への 4xx、5xx、または 6xx 応答を送信した場合は、その応答に対する ACK を決して受信することはありません。

  • UDP 使用時の再送信プロセス - SIP では、UDP などの信頼性の低い転送が使われている場合に、送信されたメッセージが再送信されることが規定されています。WebLogic Communications Server は、この仕様に従って再送信プロセスを自動的に実行します。

多くの場合、HTTP Servlet ではアプリケーションがヘッダ フィールドを明示的に設定したり調べたりする必要はありません。HTTP サーブレット コンテナが Content-Length や Content-Type などのフィールドを自動的に管理するからです。SIP Servlet にも同じヘッダ管理機能があります。

ただし、SIP ではメッセージ配信に関する重要な情報を入れるフィールドがいくつかあるので、これらのヘッダをアプリケーションで変更することは許されません。SIP サーブレットで変更できないヘッダは「システム ヘッダ」と呼ばれます。以下の表はシステム ヘッダを示します。

表 1-3 システム ヘッダ

ヘッダ名

説明

Call-ID

複数の SIP メッセージを Call として関連付けるための ID 情報が含まれます。

From、To

SIP リクエストの送信者と受信者に関する情報 (SIP、URI など) が含まれます。サーブレット コンテナによってタグ パラメータが与えられます。

CSeq

シーケンス番号とメソッド名が含まれます。

Via

SIP メッセージが通過したサーバのリストが含まれます。これはリクエストへの応答を送信するために経路を追跡したい場合に使用します。

Record-Route、Route

プロキシ サーバが後続のリクエストを仲介するときに使われます。

Contact

端末間の直接的なコミュニケーションに使われるネットワーク情報 (IP アドレスやポート番号など) が含まれます。REGISTER メッセージ、3xx、または 485 応答については、これはシステム ヘッダと見なされないので、SIP サーブレットがこの情報を直接編集することができます。


1.2.5.3 ユーティリティ機能

SIP Servlet では、SIP サーブレットで使用できる次のユーティリティが定義されています。

  1. SIP セッション、アプリケーション セッション

  2. SIP ファクトリ

  3. プロキシ

1.2.5.3.1 SIP セッション、アプリケーション セッション

前述したように、SIP Servlet は「SIP セッション」を提供し、その概念は HTTP セッションと同じです。HTTP では、Cookie などの情報を使って複数のトランザクションが関連付けられます。SIP では、この関連付けがヘッダ情報 (Call-ID および From と To のタグ パラメータ) を使って行われます。サーブレット コンテナが SIP セッションを保守し管理します。同じダイアログ内のメッセージは同じ SIP セッションを参照できます。また、ダイアログを作成しないメソッド (MESSAGE など) の場合、同じヘッダ情報を持つメッセージをセッションとして管理することができます。

SIP Servlet には「アプリケーション セッション」という概念がありますが、これは HTTP Servlet にはないものです。アプリケーション セッションとは、複数の SIP セッションおよび HTTP セッションを関連付けて管理するためのオブジェクトです。これは B2BUA などのアプリケーションに適しています。

1.2.5.3.2 SIP ファクトリ

SIP ファクトリ (SipFactory) は、アプリケーションの実行に必要な SIP Servlet 固有のオブジェクトを作成するためのファクトリ クラスです。次のオブジェクトを生成することができます。

表 1-4 SipFactory で生成されるオブジェクト

クラス名

説明

URI、SipURI、Address

文字列から SIP URI などのアドレス情報を生成できます。

SipApplicationSession

新しいアプリケーション セッションを作成します。SIP サーブレットが新しい SIP シグナル プロセスを開始するときに呼び出されます。

SipServletRequest

SIP サーブレットが UAC として振る舞ってリクエストを作成するときに使われます。このようなリクエストは Proxy.proxyTo と一緒に送信することができません。SipServletRequest と共に送信する必要があります。


SipFactory はサーブレット コンテキスト属性のデフォルト名の下に置かれます。次のコードでこれを得ることができます。

ServletContext context = getServletContext();
SipFactory factory =
    (SipFactory) context.getAttribute("javax.servlet.sip.SipFactory");
1.2.5.3.3 プロキシ

プロキシはリクエストをプロキシするために SIP サーブレットによって使用されるユーティリティです。SIP では、プロキシ処理にフォークなどの独自のシーケンスがあります。Proxy によるプロキシ処理では以下の設定を指定することができます。

  • 再帰的ルーティング (recurse) - プロキシ処理の宛先が 3xx 応答を返した場合、リクエストは指定のターゲットにプロキシされます。

  • Record-Route の設定 - 指定されたリクエストで Record-Route ヘッダを設定します。

  • パラレル/シーケンシャル (parallel) - フォークをパラレルに実行するかシーケンシャルに実行するかを決定します。

  • ステートフル - プロキシ処理がトランザクション ステートフルかどうかを決定します。ステートレス プロキシ モードは JSR289 で非推奨になったため、このパラメータは無関係です。

  • スーパーバイジング モード - プロキシ処理の状態が変化した場合 (応答受領)、アプリケーションはこれを報告します。