特集
次世代XML Webサービスを試す Part 3
SOAPメッセージのルーティング(後編)

6.WS-Referralを利用したルーティング(2)

インフォテリア株式会社
吉松 史彰
2003/02/27

Page1 Page2 Page3 Page4 Page5 Page6

 これでサーバ側が実装できた。クライアント側では、ルータを自分で実装した場合と同様に、取りあえず自分から直接送信する相手として、ルータを指定すればいいことになる。クライアントのコードはルータを自分で実装したときに使ったコードと同じだ。

static void Main(string[] args) {
  localhost.Service1 svc = new localhost.Service1();
  SoapContext ctx = svc.RequestSoapContext;
  ctx.Path.Fwd.Add(new Via(
          new Uri("http://localhost/WSERouting/router.ashx")));
  Console.WriteLine(svc.Echo("hello"));
}
Webサービス・クライアント
ルータを自分で実装したときのクライアントとまったく同じ内容。

 このクライアント・アプリケーションを実行すると、次のようなメッセージがrouter.ashxに送信される。to要素にService1.asmxが設定されている。fwd/via要素にはrouter.ashxしか設定されていないことに注意してほしい。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsrp:path
        soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
        soap:mustUnderstand="1"
        xmlns:wsrp="http://schemas.xmlsoap.org/rp">
      <wsrp:action>http://tempuri.org/Echo</wsrp:action>
      <wsrp:to>
        http://localhost/WSERouting/Service1.asmx
      </wsrp:to>
      <wsrp:fwd>
        <wsrp:via>
          http://localhost/WSERouting/router.ashx
        </wsrp:via>
      </wsrp:fwd>
      <wsrp:id>
        uuid:074e4508-83e2-4c80-8c2b-b19a03f46073
      </wsrp:id>
    </wsrp:path>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-02-01T13:00:05Z</wsu:Created>
      <wsu:Expires>2003-02-01T13:05:05Z</wsu:Expires>
    </wsu:Timestamp>
  </soap:Header>
  <soap:Body>
    <Echo xmlns="http://tempuri.org/">
      <input>hello</input>
    </Echo>
  </soap:Body>
</soap:Envelope>
クライアントからrouter.ashxに送信されるSOAPメッセージ
to要素にService1.asmxが設定される。fwd/via要素にはrouter.ashxしか設定されていない。

 これを受信したrouter.ashx(RoutingHandler)は、Web.configにリファラル文書の指定があるのを確認して、referral.xmlを読み込む。結果として、メッセージのto要素に指定されているService1.asmxに至る経路が生成される。経路の先頭はa.ashxなので、router.ashxはa.ashxに次のSOAPメッセージを送信する。fwd/via要素が増えて、経路が設定されているのが分かるだろう。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-02-01T13:00:05Z</wsu:Created>
      <wsu:Expires>2003-02-01T13:05:05Z</wsu:Expires>
      <wsu:Received Actor="http://localhost/WSERouting/router.ashx"
          Delay="1317">
        2003-02-01T13:00:11Z
      </wsu:Received>
    </wsu:Timestamp>
    <wsrp:path
        soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
        soap:mustUnderstand="1"
        xmlns:wsrp="http://schemas.xmlsoap.org/rp">
      <wsrp:action>http://tempuri.org/Echo</wsrp:action>
      <wsrp:to>
        http://localhost/WSERouting/Service1.asmx
      </wsrp:to>
      <wsrp:fwd>
        <wsrp:via>http://localhost/WSERouting/a.ashx</wsrp:via>
        <wsrp:via>http://localhost/WSERouting/b.ashx</wsrp:via>
        <wsrp:via>http://localhost/WSERouting/c.ashx</wsrp:via>
      </wsrp:fwd>
      <wsrp:id>
        uuid:074e4508-83e2-4c80-8c2b-b19a03f46073
      </wsrp:id>
    </wsrp:path>
  </soap:Header>
  <soap:Body>
    <Echo xmlns="http://tempuri.org/">
      <input>hello</input>
    </Echo>
  </soap:Body>
</soap:Envelope>
router.ashxがa.ashxに送信するSOAPメッセージ
router.ashxでは、referral.xmlを読み込み、Service1.asmxに至る経路を生成して、fwd/via要素に設定する。

 a.ashx、b.ashx、c.ashxの3つはそれぞれNopRouterクラスが処理を行う(というより何も行わずに転送する)。c.ashxはService1.asmxに次のようなSOAPメッセージを転送することになる。すべてのfwd/via要素が削除されて、タイムスタンプがきちんと生成されているのが分かるだろう。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-02-01T13:00:05Z</wsu:Created>
      <wsu:Expires>2003-02-01T13:05:05Z</wsu:Expires>
      <wsu:Received
          Actor="http://localhost/WSERouting/router.ashx"
          Delay="1317">
        2003-02-01T13:00:11Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/a.ashx" Delay="407">
        2003-02-01T13:00:12Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/b.ashx" Delay="417">
        2003-02-01T13:00:12Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/c.ashx" Delay="438">
        2003-02-01T13:00:12Z
      </wsu:Received>
    </wsu:Timestamp>
    <wsrp:path
        soap:actor="http://schemas.xmlsoap.org/soap/actor/next"
        soap:mustUnderstand="1"
        xmlns:wsrp="http://schemas.xmlsoap.org/rp">
      <wsrp:action>http://tempuri.org/Echo</wsrp:action>
      <wsrp:to>http://localhost/WSERouting/Service1.asmx</wsrp:to>
      <wsrp:id>uuid:074e4508-83e2-4c80-8c2b-b19a03f46073</wsrp:id>
    </wsrp:path>
  </soap:Header>
  <soap:Body>
    <Echo xmlns="http://tempuri.org/">
      <input>hello</input>
    </Echo>
  </soap:Body>
</soap:Envelope>
最後の中継者c.ashxからService1.asmxへ送信されるSOAPメッセージ

 Service1.asmxは処理結果を元の経路へ戻す。結果はすべてのルータを通ってクライアントへ戻されるので、クライアントが受け取るメッセージは次のようになる。

<soap:Envelope
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Header>
    <wsu:Timestamp
        xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
      <wsu:Created>2003-02-01T13:00:13Z</wsu:Created>
      <wsu:Expires>2003-02-01T13:05:13Z</wsu:Expires>
      <wsu:Received
          Actor="http://localhost/WSERouting/c.ashx" Delay="519">
        2003-02-01T13:00:13Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/b.ashx" Delay="539">
        2003-02-01T13:00:13Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/a.ashx" Delay="549">
        2003-02-01T13:00:13Z
      </wsu:Received>
      <wsu:Received
          Actor="http://localhost/WSERouting/router.ashx"
          Delay="559">
        2003-02-01T13:00:13Z
      </wsu:Received>
    </wsu:Timestamp>
  </soap:Header>
  <soap:Body>
    <EchoResponse xmlns="http://tempuri.org/">
      <EchoResult>
        hello Processed by http://localhost/WSERouting/a.ashx
      </EchoResult>
    </EchoResponse>
  </soap:Body>
</soap:Envelope>
最終的にクライアントが受け取るSOAPメッセージ

 以上がリファラル文書を使った経路の設定方法である。

経路の動的変更

 リファラル文書(この場合はreferral.xml)では、ルータが稼働するとロックされて書き込みができなくなる。経路を変更したい場合には、別の名前でリファラル文書を新しく作成し、Web.configを書き換えて新しい名前を指すようにする。Web.configはルータの稼働中でも書き換えられるので、結果として新しい経路を設定できるようになる。これにより、次のメッセージから新しい経路が設定される。

 また、SoapContextクラスのReferralsプロパティを利用すれば、SOAPメッセージのHeader要素の一部としてリファラル文書を送信することができる。リファラル文書はクライアント側でも利用することができるので、サーバとクライアントとでリファラル文書を提供し合うようなWebサービスを作れば、RIP(Routing Information Protocol)やOSPF(Open Shortest Path First)などのルーティング・プロトコルのように、自律的に経路を変更できるルータを開発することも可能だ。

今回のまとめ

 今回はWSEが実装している仕様であるWS-RoutingとWS-Referralについて解説した。これら2つの仕様はまだいわゆる標準ではないものの、WS-Routingについてはすでに幾つかの実装が存在する。SOAP仕様自体にもSOAPメッセージを中継することについて記述されている以上、このような仕様がいずれたくさんの製品に実装されるであろうことは想像に難くない。

 次回は本連載のラストを飾る、SOAPメッセージに添付ファイルを付ける機能について解説する。End of Article


 INDEX
  [特集]次世代XML Webサービスを試す Part 3
  SOAPメッセージのルーティング
    1.SOAPメッセージのルーティングを規定するWS-Routing
    2.WSEでのWS-Routing利用
    3.WS-RoutingのSOAPメッセージ
    4.WSEによるルータの実装
    5.WS-Referralを利用したルーティング(1)
  6.WS-Referralを利用したルーティング(2)
 
 「特集:次世代XML Webサービスを試す」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間