3. WebOTX SIP Application Serverの提供する機能

ここではWebOTX SIP Application Serverの提供する機能について説明します。

3.1. Web/SIP統合型コンテナ

WebOTX SIP Application Serverは、Web/SIP統合型コンテナ、Webサーバ、EJBコンテナの三つにより構成されます。ここでは、WebOTX SIP Application Serverの主要な機能であるWeb/SIP統合型コンテナについて説明します。

Web/SIP統合型コンテナ

Web/SIP統合型コンテナは、Webコンテナ機能にSIPを扱うための機能を実装した高機能なアプリケーションサーバ・コンポーネントです。Web/SIP統合型コンテナは、以下の仕様に準拠しています。

詳細についてはSIP Servlet API の仕様書をダウンロードし、参照してください。

Web/SIP統合型コンテナは、従来から提供しているWebOTXのWebコンテナ機能を継承しています。ブラウザからのHTTPリクエストをWebサーバを通して受け取り、HTTPサーブレットや JSPなどのWebアプリケーションを実行し、その結果をブラウザに返却することができます。さらにSIPコンテナ機能を実装しており、SIPアプリケーションの実行も可能になっています。

Web/SIP統合型コンテナは、WebとSIPのアプリケーションを管理します。SIPアプリケーションの管理は、Webアプリケーションと同じくサーブレットコンテキスト単位で行います。ひとつのサーブレットコンテキストには、複数のSIPサーブレットを含むことができます。アプリケーションディレクトリの構成は、Webアプリケーションとほぼ同様です。Web/SIP統合型アプリケーションの構成は以下のようになります。

/index.html
/register.html
/WEB-INF/sip.xml
/WEB-INF/web.xml
/WEB-INF/lib/mylibrary.jar
/WEB-INF/classes/Register.class
/WEB-INF/classes/WakeupCall.class

sip.xmlは、SIPサーブレット定義ファイルです。web.xmlは、HTTPサーブレット定義ファイルです。"/WEB-INF/classes"配下や"/WEB-INF/lib"に置くJavaクラスファイルはSIPサーブレットでもHTTPサーブレットでもどちらでも配置できます。

補足:HTTPサーブレットやJSPを使用せず、SIPサーブレットのみ使用するアプリケーションの場合、web.xmlは不要です。

sip.xml

sip.xmlは、Webアプリケーションのweb.xmlに相当するSIPサーブレット定義ファイルです。以下に例を示します。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sip-app
PUBLIC "-//Java Community Process//DTD SIP Application 1.0//EN"
"http://www.jcp.org/dtd/sip-app_1_0.dtd">

<sip-app>
<display-name>Simple UAS SIP Servlet</display-name>
<distributable/>

<servlet>
<servlet-name>SimpleUAS</servlet-name>
<servlet-class>test.simple.SimpleUAS</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>SimpleUAS</servlet-name>
<pattern>
<equal>
<var>request.method</var>
<value>INVITE</value>
</equal>
</pattern>
</servlet-mapping>

<!-- system user for the run-as element for Registrar -->
<security-role>
<role-name>system-user</role-name>
</security-role>
</sip-app>

rootエレメントには、sip-appを使用します。display-nameやcontext-param、servletエレメントはweb.xmlの場合と同様です。

servlet-mappingエレメントのpatternエレメントは、サーブレットの呼び出し条件を指定するSIP固有の記述です。
patternエレメントにequalを指定するとvarで指定した変数がvalueで指定した値と等しい時にTrueとなります。

上記の例では、ユーザエージェントからのリクエストがINVITEの場合に、SimpleUASが呼び出されます。

SIPメッセージング

Web/SIP統合型コンテナは、ユーザエージェントやSIPサーバから受信したSIPメッセージを解析し、SIP Servlet APIで規定されたオブジェクトとしてSIPサーブレットに引き渡します。
また、SIPサーブレットが生成したSIPメッセージのオブジェクトをSIPのデータとしてユーザエージェントやSIPサーバに送信します。

受信したSIPメッセージに対する送信は基本的にSIPサーブレットで行う必要がありますが、以下のSIPメッセージに対してはWeb/SIPコンテナで自動的にレスポンスを返すため、SIPサーブレットでの対応は必要ありません。

SIPセッション管理

SIPセッションは、ユーザエージェントとユーザエージェント、つまり端末と端末のつながりであり、SIPの呼やダイアログに相当します。Web/SIP統合型コンテナでは、SipSessionオブジェクトとしてこれを管理します。また、HttpSessionとSipSessionの両方をまとめるセッションとして、SipApplicationSessionがあります。

3.2. SIPサーブレット機能

Web/SIP統合型コンテナは、SIPサーブレットの実行を可能とします。SIPサーブレットは、HTTPサーブレットの拡張として開発されたもので、HTTPサーブレットと同様のサーブレットアーキテクチャの上に実装されています。

SIPサーブレットは、SIPサーブレットのみ、またはWebアプリケーションとセットにして、Web/SIP統合型コンテナ上に配備することができます。

RFC 3261 SIPでは、ユーザエージェントに対してサービスを提供するSIPサーバとして、SIPプロキシサーバ、レジストラサーバ、リダイレクションサーバが規定されています。SIPサーブレットを開発することにより、これらのSIPサーバの役目をWebOTX SIP Application Serverに行わせることができます。 これら三種のSIPサーバのためのSIPサーブレットのサンプルプログラムは、WebOTX SIP開発環境に含まれています。

SIPサーブレットは、HTTPサーブレットと同様にGeneric Servlet APIという共通APIをベースとしているため、SIPサーブレットとHTTPサーブレットは非常に似ています。 このためサーブレット開発者は容易に通信系サービスのアプリケーションを開発することができます。

SIPサーブレットを使用することで、Webと映像・音声のテレコミュニケーションを連携させた新たなサービスが提供できます。

SIPサーブレットとHTTPサーブレットのソースコードは似ています。

簡単なSIPサーブレット例
package com.nec.example.simple;
import java.io.*;
import javax.servlet.*;
import javax.servlet.sip.*;

public class SimpleSIPServlet extends SipServlet {
    protected void doInvite(SipServletRequest req) throws ServletException, IOException{
         SipServletResponse res = req.createResponse(200);
         res.send();
    }
}
簡単なHTTPサーブレット例
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class SimpleServlet extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse resp)  throws ServletException, IOException {
      resp.setContentType("text/html");
      PrintWriter out = resp.getWriter();
      out.println("<HTML>");
    out.println("<BODY>");
      out.println("<H1>Hello</H1>");
      out.println("</BODY><HTML>");
  }
}

HTTPサーブレットでは、doGetやdoPostのメソッドが、HTTPリクエストに対するコールバックメソッドとなっています。SIPサーブレットでは、doInviteなどのメソッドが、SIPメッセージに対するコールバックメソッドです。

SIPリクエストメッセージに対するコールバックメソッドには次のものがあります。

doInvite SIP INVITE リクエスト処理用
doAck SIP ACK リクエスト処理用
doOptions SIP OPTIONS リクエスト処理用
doBye SIP BYE リクエスト処理用
doCancel SIP CANCEL リクエスト処理用
doRegister SIP REGISTER リクエスト処理用
doPrack SIP PRACK リクエスト処理用
doSubscribe SIP SUBSCRIBE リクエスト処理用
doNotify SIP NOTIFY リクエスト処理用
doMessage SIP MESSAGE リクエスト処理用
doInfo SIP INFO リクエスト処理用

コールバックメソッドに含まれていないSIPメソッドを受信したときに、コールバックメソッドを実行したい場合や、上記のメソッドが実行される前にコールバックしたい場合に、doRequestメソッドを使用してください。

SIPサーブレットは、SIPユーザエージェント(SIP端末)やSIPサーバからのSIPリクエストメッセージを受信し、その結果としてSIPレスポンスメッセージを返却することができます。
さらにSIPサーブレットは、SIPリクエストメッセージを送信し、SIPユーザエージェントやSIPサーバからSIPレスポンスメッセージを受信することができます。
HTTPサーブレットの場合、ブラウザからのHTTPリクエストを受け取り、HTTPレスポンスを返すという片方向のクライアント・サーバ通信であるため、双方向のSIPメッセージを送受信できることは、SIPサーブレットの大きな特徴です。

SIPサーブレットは、UAからのSIPレスポンスメッセージを受け取ったとき、コールバックメソッドを実行することができます。SIPレスポンスメッセージに対するコールバックメソッドには以下のものがあります。

doProvisionalResponse SIP 1xxレスポンス処理用
doSuccessResponse SIP 2xxレスポンス処理用
doRedirectResponse SIP 3xxレスポンス処理用
doErrorResponse SIP 4xx,5xxおよび6xxレスポンス処理用

上記のメソッドが実行される前にコールバックしたい場合に、doResponseメソッドを使用してください。

SIPサーブレットとHTTPサーブレットには以下のような違いがあります。

  1. コールバックメソッドの引数
    HTTPサーブレットは、HTTPリクエストを受け取り、HTTPレスポンスを返却することが決まっています。このため、doGetなどのHTTP Servlet APIのメソッドは、引数を二つとります。
    public void doGet(HttpServletRequest request,HttpServletResponse response)
    しかし、SIPサーブレットは、SIPメッセージを受け取ってもすぐに応答返さないことがあります。そのため、SIP Servlet APIのdoInviteなどのメソッドは、引数は一つのみです。
    public void doInvite(SipServletRequest req)
  2. HTTPサーブレットは、レスポンスを受け取ることはありませんが、SIPサーブレットはレスポンスを受け取ることがあります。つまり、SIPサーブレットがユーザエージェントクライアント(UAC)として動作した場合、ユーザエージェントサーバ(UAS)からレスポンスを受信します。そのため、先のdoResponseなどのメソッドが用意されています。
  3. HTTPサーブレットは、サイズの大きなHTMLデータやコンテンツを扱うことができます。しかし、SIPは通話においてのセッション(呼)の確立が主目的であるため、大きなコンテンツは扱いません。実際の通話においてはRTP(Realtime Transport Protocol)が使用されますが、SIPサーブレットはRTPのためのSDPを定義するのみで、RTPでの通信自体には関係しません。


3.3. WebアプリケーションからのSIPの利用

Web/SIP統合型コンテナ上で動作するWebアプリケーションは、SIP Servlet APIに規定されるSIPメッセージ送信機能を利用することができます。これにより、ブラウザからの指示により電話を発呼するなど、映像・音声コミュニケーションとWebを連携させることができます。

SIP Servlet APIでは、javax.servlet.sip.SipFactoryインタフェースが規定されており、これに基づいたファクトリをWeb/SIP統合型コンテナは持っています。SIPサーブレットは元より、WebアプリケーションからもSipFactoryは参照可能です。SipFactoryを使用すると、SipApplicationSessionオブジェクトの作成やSipServletRequestオブジェクトの作成が可能となり、WebアプリケーションからSIPメッセージを送信することができます。

SIPサーブレットとHTTPサーブレットやJSPの間でオブジェクトを受け渡す場合、javax.servlet.ServletContextインタフェースを使用することができます。 たとえば、SIPサーブレットでsetAttributeメソッドによりオブジェクトを登録し、HTTPサーブレットでgetAttributeメソッドにより参照することができます。


3.4. SIPプロキシ機能

SIP Servlet APIには、SIPサーブレットをプロキシとして動作させるためのAPIが規定されています。これによりSIPサーブレットは、ユーザエージェントから受け取ったSIPリクエストメッセージを任意のUAまたはSIPサーバに対して転送することができます。

WebOTX SIP Application Serverのサンプルプログラムには、SIPプロキシサーバの例が含まれています。


3.5. SIPスタック

SIPスタックは、ユーザエージェントやSIPサーバからのSIPメッセージを受信し、SIPサーブレットに渡します。また、SIPサーブレットやHTTPサーブレットが作成したSIPメッセージを送信します。

3.6. SIPメッセージ仮想化機能

SIPサーブレットが送受信するメッセージの内容をあらかじめ指定した規則に基づき、変更する機能を提供します。SIPサーバやUA毎にプロトコル仕様に差異がある場合や独自の機能拡張も行われている場合、SIPアプリケーションの開発者は、対応するユーザエージェントやSIPサーバごとにアプリケーションを書き直す必要があります。WebOTX SIP Application Serverでは、この問題を解決するために、同一のSIPアプリケーションで異なるSIPサーバとの連携を可能とします。仮想化機能は以下のタイミングで動作します。ユーザエージェントやSIPサーバはUAとして示します。

つまりUAとSIPサーブレットの間でWeb/SIP統合型コンテナ内で自動的にメッセージの変換処理を行います。変換は、SIPおよびSIPメッセージボディに記載されるSDPに対して行うことができます。

注意:変換規則によりRFC3261 SIPから大きく逸脱したメッセージができる場合、正しく送信できずエラーが発生することがあります。

仮想化機能を使用する場合、以下の二つの設定が必要です。

nec-sipconv.xmlは、仮想化の規則を示します。
sip-appエレメント、sip-convエレメントの内部に規則を記載します。仮想化対象のSIPメッセージの選択は、<var>,<value>,<type>の値により指定します。

var

value

SIPメッセージ識別子

SIPメソッド名

Request-Methodのみ有効

INVITE,BYE

(SIPメッセージの第一行の行頭からの文字列一致でよいので、記載されたメソッド名が正しいSIPのメソッド名かどうかは意識しない)

あて先のSIP URI

Request-URI のみ有効

sip:bishop@1.2.3.4

(SIPメッセージの第一行のRequest-URI部分の文字列一致で対象かどうかを比較する)

SIPヘッダ名

Via, User-Agentなど

(SIPヘッダ部の行頭からの文字列一致でよいので、記載されたヘッダ名が正しいSIPのヘッダ名かどうかは意識しない)

User-Agentであれば" Softphone Beta1.5"のようなUAの名前

すべてのSIPメッセージ

"*"のみ有効

 

"-"

 

<type>エレメントは以下の値から選択してください。

typeの値

意味

request.inbound

UAから受け取ったリクエスト

request.outbound

UAに送信するリクエスト

response.inbound

UAから受け取ったレスポンス

response.outbound

UAに送信するレスポンス

処理内容は、<command>エレメントで設定します。

commandの値

概要

ADDHEADER

存在しない行の追加(行データは固定)

DELHEADER

存在する行の削除(ヘッダ名で固定)

ADDPARAM

存在しないパラメータの追加(パラメータ名・値は固定

DELPARAM

存在するパラメータの削除(パラメータ名で固定

REPLACE

存在する特定文字列変換(文字列完全一致で、固定文字列に変換)

<sip-conv>,<var>,<value>,<type>で一つの規則を示します。nec-sipconv.xml内に複数の規則を記述できます。
sip-conv.xmlの読み込みおよびフォーマット解析に失敗した場合、Web/SIPアプリケーションのロードに失敗します。失敗したかどうかは、webotx_agent.logの出力により確認できます。
<var>で指定する値は、完全一致です。大文字・小文字は区別します。
<value>で指定する値は、部分一致です。大文字・小文字は区別しません。
複数の<var>と<value>(複数のsip-convブロック)で指定したSIPメッセージ識別子が一つのSIPメッセージにマッチする場合、最初にマッチした<sip-conv>のみSIPメッセージに適用し、以降のsip-convは無視します。

<sip>および<sdp>メンバはどちらか一方を使用します。<sip>はSIPヘッダ内の変換を、<sdp>はSDP内の変換を示します。
<sip>の<command>が"ADDHEADER"のとき、<header>で指定可能なpos属性値には、以下のものが使用できます。

属性値

内容

top

SIPヘッダの先頭行に追加する

bottom

SIPヘッダの最終行に追加する

(ただし、Content-Lengthヘッダは必ず最終行になるため、その上になる)

属性値なし

bottomと同じ

<sdp>ブロックの<sdpheader>ブロックで指定可能なpos属性値には、以下のものが使用できます。

属性値

内容

sessiontop

session記述部の先頭行に追加する

sessionbottom

session記述部の最終行に追加する

mediatop

メディア記述部は複数存在する可能性がある、全メディア記述部の先頭行に追加する

mediabottom

全メディア記述部の最終行に追加する

属性値なし

sessionbottomと同じ

以下に例を示します。  

<!DOCTYPE sip-app PUBLIC
"-//(C) NEC Corporation//DTD SIP CONV 1.0//EN"
"http://www.nec.co.jp/dtd/sipconv_10.dtd">

<sip-app>
<sip-conv>
<var>Request-Method</var>
<value>INVITE</value>
<type>request.inbound</type>
<sip>
<command>ADDHEADER</command>
<header>TESTHEADER:ABC</header>
</sip>
</sip-conv>
</sip-app>

この例では、INVITEのSIPリクエストメッセージがSIPサーブレットに渡る前に、TESTHEADERのSIPヘッダ行を追加します。
<!DOCTYPE sip-app PUBLIC
"-//(C) NEC Corporation//DTD SIP CONV 1.0//EN"
"http://www.nec.co.jp/dtd/sipconv_10.dtd">

<sip-app>
<sip-conv>
<var>*</var>
<value>-</value>
<type>response.inbound</type>
<sip>
<command>DELPARAM</command>
<header>MyHeader</header>
<paramname>myparam</paramname>
</sip>
</sip-conv>
</sip-app>

この例では、すべてのSIPレスポンスメッセージがSIPサーブレットに渡る前に、MyHeaderのSIPヘッダ行からmyparam値を削除します。
<!DOCTYPE sip-app PUBLIC
"-//(C) NEC Corporation//DTD SIP CONV 1.0//EN"
"http://www.nec.co.jp/dtd/sipconv_10.dtd">

<sip-app>
<sip-conv>
<var>*</var>
<value>-</value>
<type>response.inbound</type>
<sdp>
<command>ADDHEADER</command>
<sdpheader>x=1</sdpheader>
</sdp>
</sip-conv>
</sip-app>

この例では、すべてのSIPレスポンスメッセージがSIPサーブレットに渡る前に、SDPのセッション記述部の最後に"x=1"を追加します。

3.7. セッション、およびタイマオブジェクトの保存と復元機能

SIPアプリケーションでは、SIPサーブレットにおいて任意のセッ ションオブジェクトやタイマを作成することが可能です。これら のオブジェクトは通常 Web/SIP統合型コンテナのライフサイクル やドメインを停止すると破棄します。

しかし、設定を行う(タイマの場合はタイマ作成時のコーディン グでも意識する必要があります)事で、ドメイン再起動時にオブ ジェクトを復元することができます。

セッション、およびタイマオブジェクトの保存と復元機能を利用 するためには、それぞれ以下の設定が必要です。
セッションオブジェクト … nec-web.xml の設定
タイマオブジェクト … nec-web.xml の設定、およびコーディングでのフラグの設定
以下にそれぞれの設定について説明します。
タイマオブジェクトを保存させるためのコーディング例を以下に示します。
具体的には、タイマオブジェクトを作成する際のフラグとして保存と復元を指示します (createTimerメソッドの引数 isPersistent を true にします)。
 ServletContext sc = getServletContext();
 SipApplicationSession sas = req.getApplicationSession();
 TimerService ts = (TimerService)sc.getAttribute(SipServlet.TIMER_SERVICE);
 int time = 90*1000;   /* 90秒間隔のタイマ */
 boolean isPersistent = true;
 String data = "任意のデータです";
 ServletTimer timer = ts.createTimer(sas , time, isPersistent, data);

nec-web.xml の設定に関しては以下をご参照ください。
  ■運用編
  2. コンフィグレーション
  2.3. 設定
  2.3.4. セッション、およびタイマオブジェクトの保存に関する設定
  
上記の設定を行うことで、Web/SIP統合型コンテナのライフサイ クルやドメインを停止する際、もしセッションオブジェクトや タイマオブジェクトが存在すれば、その内容をファイルに保存し ます。以下がその出力場所です。
    <ドメインディレクトリ>/generated/jsp/j2ee-modules/<コンテキスト名>
    
そして、次回 Web/SIP統合型コンテナのライフサイクルやドメイ ンを起動した際に復元します。 なお、本機能を利用するにあたっての注意事項がありますので合わせて注意制限事項をご覧ください。
    ■注意制限事項
    1.1. 注意事項