Fusion Middleware Oracle WebLogic Server Microsoft .NET対応のWebLogic JMSクライアントの使用

11gリリース1 (10.3.6)

B55555-05(原本部品番号:E13746-05)

目次

タイトルおよび著作権情報

はじめに

- ドキュメントのアクセシビリティについて

- 表記規則

1 WebLogic JMS .NETクライアントの概要

- WebLogic JMS .NETクライアントとは

- サポートされるJMSの機能

- メッセージング・モデル

- メッセージ・タイプ

- WebLogic JMS .NETクライアントの仕組み

- WebLogic Serverの構成

- リスニング・ポートの構成

- JMS .NETクライアント用のJMSリソースの構成

- 以前のリリースのWebLogic Serverとの相互運用

- WebLogic JMS .NET APIについて

2 WebLogic JMS .NETクライアント・ライブラリのインストールおよびコピー

- WebLogic JMS .NETクライアントのインストール

- インストールされたコンポーネントの場所

- クライアント・マシンへのライブラリのコピー

3 WebLogic JMS .NET APIを使用した基本的なJMSアプリケーションの開発

- JMS .NETクライアント・アプリケーションの作成

- 例:基本的なPTP JMS .NETクライアント・アプリケーションの記述

- 前提条件

- 基本的な手順

- 手順1

- 手順2

- 手順3

- 手順4

- 手順5

- 手順6

- 手順7

- 手順8

- 手順9

- 手順10

- JMS .NETクライアント・アプリケーションでの高度な概念の使用

4 プログラミングの考慮事項

- WebLogic JMS拡張機能の使用

- メッセージの圧縮

- 順序単位

- メッセージ配信時間

- 一方向のメッセージ送信

- JMSXUserIdとしてのuser-idの使用

- メッセージ配信の試行

- WebLogic JMS .NETクライアントの使用に関する制限事項

- サポートされないJMS 1.1の標準機能

- サポートされないJMS 1.1のオプション機能

- サポートされないWebLogic JMS拡張機能

- トランザクション

- 異なる言語環境間でのメッセージの交換

- URLフォーマットの指定

- DNS別名ホスト名の使用

- JMS .NETクライアントでのセキュリティの実装

- ロギングとデバッグの構成

- サーバー側

- クライアント側

- メッセージ出力

- ログのカテゴリとレベル

- ソケットとスレッドの動作について

- Javaおよび.NET間のデータ変換

- エンディアンの変換

- 符号付きバイトと符号なしバイトの変換

- バイト配列の転送

- 時間の変換

- ベスト・プラクティス

A JMS .NETクライアント・サンプル・アプリケーション

Oracle® Fusion Middleware

Oracle WebLogic Server Microsoft .NET対応のWebLogic JMSクライアントの使用

11gリリース1 (10.3.6)

B55555-05(原本部品番号:E13746-05)

2011年11月

このマニュアルは、WebLogic JMSリソースにアクセスできるJMS .NETクライアント・アプリケーションを開発するアプリケーション開発者を対象としています。

Oracle Fusion Middleware Oracle WebLogic Server Microsoft .NET対応のWebLogic JMSクライアントの使用, 11gリリース1 (10.3.6)

B55555-05

Copyright © 2007, 2011, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007).Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション（人的傷害を発生させる可能性があるアプリケーションを含む）への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性（redundancy）、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

はじめに

ここでは、このガイド『Oracle WebLogic Server Microsoft .NET対応のWebLogic JMSクライアントの使用』で使用されるドキュメントのアクセシビリティ機能と規則について説明します。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイトhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=docaccを参照してください。

Oracleサポートへのアクセス

Oracleのお客様は、My Oracle Supportにアクセスして電子サポートを受けることができます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害のあるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

表記規則

このマニュアルでは次の表記規則を使用します。

規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

斜体

イタリックは、ユーザーが特定の値を指定するプレースホルダー変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 WebLogic JMS .NETクライアントの概要

この章ではWebLogic JMS .NETクライアントの概要を示し、JMS .NETクライアント・アプリケーションからWebLogic JMSリソースにアクセスする方法について解説します。また、WebLogic JMS .NET APIについても簡単に説明します。

ここでは、.NETのプログラミングおよびJMS 1.1の概念と機能に精通している読者を対象としています。

- WebLogic JMS .NETクライアントとは

- WebLogic JMS .NETクライアントの仕組み

- WebLogic Serverの構成

- 以前のリリースのWebLogic Serverとの相互運用

- WebLogic JMS .NET APIについて

WebLogic JMS .NETクライアントとは

WebLogic JMS .NETクライアントは完全に管理された.NET実行時ライブラリとアプリケーション・プログラミング・インタフェース(API)です。このクライアントを使用すると、プログラマはWebLogic Java Message Service (JMS)のアプリケーションとリソースにアクセスできる.NET C#クライアント・アプリケーションを作成できます。

WebLogic JMSは、JMS 1.1仕様(http://www.oracle.com/technetwork/java/jms/index.html)を完全にサポートするエンタープライズ・レベルのメッセージング・システムで、標準のJMS APIに加えて、多数のWebLogic JMS拡張も提供しています。WebLogic ServerのJMSの付加価値機能の概要は、『Oracle WebLogic Server JMSの構成と管理』の「WebLogic ServerのJMSの付加価値機能」を参照してください。

JMS .NET APIのすべてのクラスとインタフェースの詳細は、Oracle WebLogic Server Microsoft .NETメッセージAPIマニュアルを参照してください。

WebLogic JMS .NETクライアントはWebLogic Server 10gリリース3以降に付属しており、Microsoft .NET Frameworkバージョン2.0から3.5まででサポートされます。インストールの詳細は、第2章「WebLogic JMS .NETクライアント・ライブラリのインストールおよびコピー」で説明します。

サポートされるJMSの機能

このリリースでは、WebLogic JMS .NETクライアントは、JMSバージョン1.1仕様(http://www.oracle.com/technetwork/java/jms/index.htmlを参照)の主な標準機能をサポートします。サポートされないJMS 1.1の標準機能のリストについては、「WebLogic JMS .NETクライアントの使用に関する制限事項」を参照してください。

標準のJMS 1.1仕様のサポートに加えて、WebLogic JMS .NETクライアントはいくつかのWebLogic JMS拡張機能もサポートしています。サポートされる機能の詳細とJMS .NETクライアントでの使用方法については、「WebLogic JMS拡張機能の使用」を参照してください。

メッセージング・モデル

WebLogic JMS .NETクライアントは以下のメッセージング・モデルをサポートしています。

- ポイント・ツー・ポイント(PTP)メッセージング・モデル。1つのアプリケーションが1つの宛先にメッセージを送信できます。

- パブリッシュ/サブスクライブ(pub/sub)メッセージング・モデル。1つのアプリケーションが複数のアプリケーションにメッセージを送信できます。

メッセージは永続または非永続として指定できます。

- 永続メッセージは確実に1回のみ配信されることが保証されています。メッセージはJMSサーバーに障害が起きても失われず、一度アプリケーションで確認応答されれば再配信されることはありません。メッセージは、ファイルまたはデータベースに正常に書き込まれるまで送信されたとは判断されません。

- 非永続メッセージは格納されません。最大で1回配信されることが保証されています。メッセージはJMSプロバイダで障害が起きると失われ、再配信されることはありません。

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージング・モデルについて」を参照してください。

メッセージ・タイプ

JMS 1.1仕様(http://www.oracle.com/technetwork/java/jms/index.htmlを参照)に定義されているように、WebLogic JMS .NETクライアントは次のメッセージ・タイプをサポートします。

- Message

- BytesMessage

- MapMessage

- ObjectMessage (同じ言語で記述されたプロデューサとコンシューマの間のみ)

- StreamMessage

- TextMessage

WebLogic JMSで提供されているXMLMessageタイプの拡張機能はこのリリースではサポートされていません。このタイプのメッセージを.NETクライアントで受信した場合は、自動的にTextMessageタイプに変換されます。

サポートされるメッセージ・タイプの使用の詳細は、「異なる言語環境間でのメッセージの交換」を参照してください。

WebLogic JMS .NETクライアントの仕組み

次の図では、.NET Framework CLRで実行されるJMS .NETクライアント・アプリケーションがWebLogic ServerにデプロイされているJMSリソースにアクセスする仕組みを示します。

図1-1 JMS .NETクライアントのアーキテクチャ

「図1-1 JMS .NETクライアントのアーキテクチャ」の説明

注意:
図1-1に示されたWebLogicコンポーネントはすべてWebLogic Server 10gリリース3以降の単一のインスタンスにホストされています。複数サーバーまたはクラスタの構成では、WebLogic Serverの各コンポーネントはWebLogic Serverの別々のインスタンス上で実行できます。ただし、JMS .NETクライアント・ホストはWebLogic Server 10gリリース3以降で実行する必要があり、接続ホストとJMSサーバーはWebLogic Server 9.x以降の同じクラスタ内で実行する必要があります。

図に示された主なコンポーネントは以下のとおりです。

- C#で記述されたJMS .NETクライアント。NET Framework CLR内で実行されます。宛先に対してメッセージを生成したり、宛先からのメッセージを消費したりします。

- WebLogic Server 10gリリース3以降で実行されるJMS .NETクライアント・ホスト。JMS .NETクライアントとWebLogic JMSの間のインタフェースを提供します。

- .NETクライアント・ホスト上に構成されている標準のT3プロトコル・リスニング・ポート。

- 1つまたは複数の接続ホスト(つまり、接続ファクトリ)。

- 一連のJMS宛先が定義されている1つまたは複数のJMSサーバー。

JMSサーバーへのトラフィックは常に、.NETクライアントからJMS .NETクライアント・ホストを通じて接続ホストへ、さらにJMSサーバーへとルーティングされます。JMS .NETクライアントへのトラフィックは常に、JMSサーバーから接続ホストへ、さらにJMS .NETクライアント・ホストを通じて.NETクライアントへとルーティングされます。

図1-1に示したような、JMS .NETクライアントとJMSサーバーの間のメッセージ交換のプロセスを簡単にまとめると、以下のようになります。

1. JMS .NETクライアントは、WebLogic Server 10gリリース3以降で実行されているJMS .NETクライアント・ホストとの間に最初のT3ネットワーク接続を確立します。

2. JMS .NETクライアントはJMS .NETクライアント・ホストから接続ファクトリを取得します。

3. JMS .NETクライアント・ホストはJNDIから接続ファクトリを取得します。

4. JMS .NETクライアントは接続ファクトリを使用して接続を作成します。JMS .NETクライアント・ホストから、接続ファクトリが存在する接続ホストの1つに向かって接続が確立されます。

5. JMS .NETクライアントがメッセージを送信(生成)すると、JMS .NETクライアント・ホストはそのメッセージを接続ホストに送信します。接続ホストは、宛先をホストしているJMSサーバーにメッセージをルーティングします。一方、JMS .NETクライアントがメッセージを受信(消費)する場合は、接続ホストが、宛先をホストしているJMSサーバーからJMS .NETクライアント・ホストへメッセージをルーティングします。JMS .NETクライアント・ホストはJMS .NETクライアントへメッセージを渡します。

JMS .NETクライアント・アプリケーションの作成手順と例については、第3章「WebLogic JMS .NET APIを使用した基本的なJMSアプリケーションの開発」で説明しています。

WebLogic Serverの構成

以下の節では、JMS .NETクライアント・アプリケーションがJMSリソースにアクセスするために必要な構成について説明します。

リスニング・ポートの構成

JMS .NETクライアントでは、JMS .NETクライアント・ホストをホストしているWebLogic Serverインスタンスで、T3プロトコル用に構成されたリスニング・ポートが有効になっている必要があります。WebLogic Serverをインストールしたときに、デフォルト・ポートはT3プロトコルを使用するように構成されます。デフォルト・ポートの構成は変更したり無効にしたりできるため、システム管理者はサーバーのデフォルト・ポートでT3プロトコルが有効になっていることを確認するか、T3プロトコルをサポートするネットワーク・チャネルを追加する必要があります。構成情報については、以下のトピックを参照してください。

- Oracle WebLogic Server管理コンソール・ヘルプの「デフォルト・ネットワーク接続の構成」

- 『Oracle WebLogic Serverサーバー環境の構成』の「ネットワーク・チャネルの理解」

JMS .NETクライアント用のJMSリソースの構成

JMS .NETクライアント・アプリケーションがWebLogic ServerにデプロイされているJMSリソースにアクセスする前に、WebLogic Serverシステム管理者は必要なJMSリソース(接続ファクトリ、JMSサーバー、宛先など)を構成しておく必要があります。JMSリソースの構成手順については、以下を参照してください:

- 『Oracle WebLogic Server JMSの構成と管理』

- Oracle WebLogic Server管理コンソール・ヘルプの「メッセージの構成」

以前のリリースのWebLogic Serverとの相互運用

JMS .NETクライアントはWebLogic Server 10gリリース3以降とのみ直接通信できます。図1-2に示すように、JMS .NETクライアント・ホストはWebLogic Server 10gリリース3以降で実行する必要があります。ただし、接続ホストとJMSサーバーはWebLogic Server 9.x以降で実行できます。接続ホストとJMSサーバーは両方とも同じクラスタ内に配置する必要があります。

図1-2 JMS .NETクライアントの相互運用性

「図1-2 JMS .NETクライアントの相互運用」の説明

宛先がWebLogic Server 9.x以降で実行されていて、WebLogic Server 10gリリース3以降で実行されている.NETクライアント・ホストと同じクラスタ内にない場合、その宛先にアクセスするには、WebLogic Serverのリモート・インスタンスを外部サーバーとして構成する必要があります。詳細は、『Oracle WebLogic Server JMSの構成と管理』の「外部サーバー・リソースからサード・パーティJMSプロバイダへのアクセスの構成」を参照してください。

注意:
JMS Javaクライアントを使用し、外部サーバーを使用してサード・パーティのJMSプロバイダに接続することもできますが、この機能はWebLogic JMS .NETクライアントではサポートされていません。

WebLogic JMS .NET APIについて

以下の表では、JMS .NETクライアント・アプリケーションの作成に使用できるJMS .NET APIの主要なクラスとインタフェースを示します。JMS .NET APIのすべてのクラスとインタフェースの詳細は、『』マニュアルを参照してください。

表1-1 WebLogic JMS .NETのクラスとインタフェース

インタフェース/クラス

説明

Constants

Constantsのクラス群は、APIで一般的に使用される定数や列挙値を定義するために使用します。

ContextFactory

ContextFactoryはコンテキストの作成に使用します。コンテキストは、.NETクライアントからクライアント・ホストへのネットワーク接続。

IContext

IContextオブジェクトは.NETクライアントからクライアント・ホストへのネットワーク接続を表現します。宛先や接続ファクトリのルックアップ、不要になったネットワーク接続のクローズに使用されます。

IConnectionFactory

IConnectionFactoryオブジェクトはJMS接続構成情報をカプセル化します。JMS .NETクライアントはIContextオブジェクトを使用して接続ファクトリをルックアップし、その接続ファクトリを使用してJMSサーバーとのIConnectionを作成します。

IConnection

IConnectionオブジェクトはJMS .NETクライアント・ホストとJMS接続ホストの間のアクティブな接続。接続の作成時に認証が行われる場合もあります。接続はセッションを作成するために使用します。

ISession

ISessionオブジェクトはメッセージを生成および消費するためのシングル・スレッドのエンティティ。セッションでは複数のメッセージ・プロデューサとコンシューマを作成して処理できます。

IDestination

IDestinationオブジェクトはキューかトピックかを識別します。キュー宛先ではポイント・ツー・ポイント・メッセージング・モデルから、トピック宛先ではpub/subメッセージング・モデルから配信されるメッセージを管理します。

ITopic

ITopicオブジェクトは、プロバイダ固有のトピック名をカプセル化したpub/subのIDestinationです。クライアントがトピックのIDをJMS APIメソッドに指定する方法となります。IDestinationをパラメータとして使用するメソッドでは、ITopicオブジェクトを引数として使用できます。たとえば、以下のメソッドを呼び出すと、ITopicを使用してIMessageConsumerとIMessageProducerを作成できます。

ISession.CreateConsumer(IDestination destination)
ISession.CreateProducer(IDestination destination)

IQueue

IQueueオブジェクトは、プロバイダ固有のキュー名をカプセル化したポイント・ツー・ポイントのIDestinationです。クライアントがキューのIDをJMS APIメソッドに指定する方法となります。

IQueueとITopicは両方ともIDestinationを継承しているため、IDestinationをパラメータとして使用するメソッドでは、IQueueオブジェクトを引数として使用できます。たとえば、以下のメソッドを呼び出すと、IQueueを使用してIMessageConsumerとIMessageProducerを作成できます。

ISession.CreateConsumer(IQueue queue)
ISession.CreateProducer(IQueue queue)

IMessageConsumer

JMS .NETクライアントはIMessageConsumerオブジェクトを使用して、宛先からメッセージを受信します。IMessageConsumerオブジェクトを作成するには、セッションで提供されるメッセージ・コンシューマ作成メソッドにIDestinationオブジェクトを渡します。

IMessageProducer

JMS .NETクライアントはIMessageProducerオブジェクトを使用して、宛先にメッセージを送信します。IMessageProducerオブジェクトを作成するには、セッションで提供されるメッセージ・プロデューサ作成メソッドにIDestinationオブジェクトを渡します。

IMessage

IMessageインタフェースはすべてのJMSメッセージのルート・インタフェース。すべてのメッセージで使用されるメッセージ・ヘッダーと確認応答メソッドを定義します。

JMSメッセージは以下の部分から構成されます。

ヘッダー - すべてのメッセージは同じヘッダー・フィールドのセットをサポートします。ヘッダー・フィールドには、メッセージの識別やルーティングのためにクライアントとプロバイダの両方で使用される値が格納されます。

プロパティ - 各メッセージには、アプリケーション定義のプロパティ値をサポートするための組込みの機能が含まれています。プロパティは、アプリケーション定義のメッセージ・フィルタリングをサポートするための効率的なメカニズムを提供します。

本文 - JMS APIでは複数のタイプのメッセージ本文を定義しています。現在使用されている主要なメッセージング方式に対応しています。

IMapMessage

IMapMessageオブジェクトは名前と値のペアを送信するために使用します。名前はStringオブジェクト、値はJavaおよびC#プログラミング言語のプリミティブ・データ型。名前には必ず値が必要であり、値をnullや空の文字列にすることはできません。このエントリには、名前を指定して順次的またはランダムにアクセスできます。エントリの順序は定義されません。IMapMessageはIMessageインタフェースを継承し、マップを格納するメッセージ本文を追加します。

IObjectMessage

IObjectMessageオブジェクトはJavaおよびC#プログラミング言語のシリアライズ可能なオブジェクトを格納したメッセージを送信するために使用します。IMessageインタフェースを継承し、オブジェクトの1つの参照を格納した本文を追加します。C#オブジェクトをJavaプログラムから、またはJavaオブジェクトをC#プログラムから読み込むことはできません。詳細は、「異なる言語環境間でのメッセージの交換」を参照。

IStreamMessage

IStreamMessageオブジェクトはJavaプログラミング言語のプリミティブ型のストリームを送信するために使用します。格納と読取りは順次的に行われます。IMessageインタフェースを継承し、ストリームのメッセージ本文を追加します。メソッドは主にjava.io.DataInputStreamとjava.io.DataOutputStreamのメソッドに基づいています。

ITextMessage

ITextMessageオブジェクトはStringを格納したメッセージを送信するために使用します。IMessageインタフェースを継承し、テキストのメッセージ本文を追加したもの。

IBytesMessage

IBytesMessageオブジェクトは未解釈のバイト・ストリームを格納したメッセージを送信するために使用します。IMessageインタフェースを継承し、バイトのメッセージ本文を追加します。メッセージの受信側でバイトの解釈を行います。

2 WebLogic JMS .NETクライアント・ライブラリのインストールおよびコピー

この章では、WebLogic ServerプラットフォームにインストールされているJMS .NETクライアント・コンポーネントについて説明します。インストール先の場所と.NET Frameworkマシンへのコピー方法も示します。

- WebLogic JMS .NETクライアントのインストール

- クライアント・マシンへのライブラリのコピー

WebLogic JMS .NETクライアントのインストール

WebLogic JMS .NETクライアントはWebLogic Server 10gリリース3以降にバンドルされています。(Windows以外のプラットフォームを含む)サポート対象のプラットフォーム上でWebLogic Serverの完全なインストールを実行すると、WebLogic JMS .NETクライアントがデフォルトでインストールされます。カスタム・インストール・オプションを選択した場合は、WebLogic ServerのWebLogic Serverクライアント・コンポーネントが選択されていることを確認してください。このコンポーネントを選択解除した場合、WebLogic JMS .NETクライアントはインストールされません。

WebLogic Serverのサポート対象プラットフォームのリストについては、『Oracle WebLogic Serverの新機能』のサポートされている構成に関する項を参照してください。

WebLogic Serverのインストールの詳細は、インストレーション・ガイドを参照してください。

インストールされたコンポーネントの場所

WebLogic JMS .NETクライアントはWebLogic Serverプラットフォーム上の以下のディレクトリにインストールされます。

MW_HOME/modules/com.bea.weblogic.jms.dotnetclient_x.x.x.x

MW_HOMEは、インストール・プロセス中にユーザーが選択した最上位のインストール・ディレクトリで、x.x.x.xは、クライアントのバージョン番号です。複数の.NETクライアント・モジュール・ディレクトリがある場合は、最新のアップデートを得るには、最新バージョンを使用することが推奨します。

インストールされたJMS .NETクライアントは以下のコンポーネントで構成されています。

- WebLogic.Messaging.dll - JMSクライアント・アプリケーションでクライアントが使用する、完全に管理されたJMS .NETクライアント・ライブラリ。

- WebLogic.Messaging.pdb - JMS .NETクライアント・アプリケーションをデバッグするために、クライアントがWebLogic.Messaging.dllと一緒に使用できるJMS .NETクライアント・ライブラリのデバッグ・バージョン。

- jms.dotnet.api.zip - WebLogic JMS .NET APIに関するHTMLおよびWindowsヘルプ形式のドキュメント。

注意:
WebLogic JMS .NETクライアントAPIのドキュメントは、Oracle WebLogic Server Microsoft .NETメッセージAPIから入手できます。

クライアント・マシンへのライブラリのコピー

サポート対象のプラットフォームにWebLogic Serverをインストールした後で、「インストールされたコンポーネントの場所」で示されたインストール・ディレクトリから、サポートされる.NETクライアント・マシン上の開発ディレクトリに、WebLogic.Messaging.dllライブラリをコピーする必要があります。また、.NETアプリケーションがそのライブラリを参照するようにする必要があります。JMS .NETクライアントは完全に管理された実行時ライブラリであり、.NET Frameworkバージョン2.0から3.5を実行する以下のWindowsプラットフォーム上でサポートされます。

- Windows 2003

- Windows XP

- Windows Vista

Visual Studioを使用している場合は、次の手順に従うと、WebLogic.Messaging.dllを参照アセンブリとしてプロジェクトに追加できます。

1. 「プロジェクト」>「参照」を選択します。

2. 「参照の追加」を選択し、上記でコピーした.NETマシン上のディレクトリのWebLogic.Messaging.dllを指定します。

また、JMS .NETクライアント・ライブラリのデバッグ・バージョンであるWebLogic.Messaging.pdbとAPIドキュメントもクライアント・マシンにコピーできますが、必須ではありません。

3 WebLogic JMS .NET APIを使用した基本的なJMSアプリケーションの開発

この章では、JMS .NET APIを使用してC#で基本的なJMSアプリケーションを開発するために必要な手順について説明します。WebLogic JMS .NETクライアントを使用するJMSアプリケーションの開発プロセスは、Javaクライアントの開発プロセスとよく似ています。

- JMS .NETクライアント・アプリケーションの作成

- 例:基本的なPTP JMS .NETクライアント・アプリケーションの記述

- JMS .NETクライアント・アプリケーションでの高度な概念の使用

JMS .NETクライアント・アプリケーションの作成

以下のフローチャートは、基本的なJMS .NETアプリケーションの手順を示したものです。

図3-1 JMS .NETクライアント・アプリケーションの基本的な手順

「図3-1 JMS .NETクライアント・アプリケーションの基本的な手順」の説明

注意:
リソースの作成やクローズは、メッセージの送信や受信と比べると、比較的オーバーヘッドが高くなります。スレッド間でコンテキストを共有し、他のリソースは再利用のためにキャッシュすることをお薦めします。詳細は、「ベスト・プラクティス」を参照してください。

例:基本的なPTP JMS .NETクライアント・アプリケーションの記述

以下の例では、C#で記述する基本的なJMS .NETクライアント・アプリケーションの作成方法を示します。自動確認応答モードを使用するように構成されたキューにおいて、同期受信を使用します。この例の完全なコピーは、付録A「JMS .NETクライアント・サンプル・アプリケーション」に記載されています。

このサンプルで使用されている.NET APIのクラスとメソッドの詳細は、「WebLogic JMS .NET APIについて」または.NETクライアント用のWebLogicメッセージングAPIリファレンスのドキュメントを参照してください。

前提条件

先に進む前に、WebLogic Serverの構成を担当するシステム管理者は、以下のものを構成しておく必要があります。

- JMS .NETクライアントをホストするサーバー上で、T3プロトコル用に構成されたリスニング・ポート。詳細は、「リスニング・ポートの構成」を参照してください。

- 必要なJMSリソース(接続ファクトリ、JMSサーバー、宛先など)。詳細は、「JMS .NETクライアント用のJMSリソースの構成」を参照してください。

基本的な手順

以下の手順では、プログラムの最初で必要な変数(WebLogic Serverホスト、接続ファクトリ、キューおよびトピック名など)を定義済みであることを前提としています。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

using WebLogic.Messaging;

public class MessagingSample
{
private string host      = "localhost";
private int    port      = 7001;
private string cfName    = "weblogic.jms.ConnectionFactory";
private string queueName = "jms.queue.TestQueue1";

手順1

WebLogic Serverホストへのネットワーク接続を確立して、必要な場合はログインするために、コンテキストを作成します。

IDictionary<string, Object> paramMap = new Dictionary<string, Object>();

paramMap[Constants.Context.PROVIDER_URL] =
"t3://" + this.host + ":" + this.port;

IContext context = ContextFactory.CreateContext(paramMap);

注意:
Provider_URLには、カンマで区切って複数のアドレスを格納できます。複数のアドレスの指定の詳細は、「URLフォーマットの指定」を参照してください。
複数のアドレスを指定した場合、コンテキストは、いずれかのアドレスが成功するか、すべてのアドレスが失敗するまで、各アドレスを順に試行します。アドレスのリスト内のランダムな位置から開始し、すべてのアドレスをローテーションします。アドレスのリスト内のランダムな位置から開始し、すべてのアドレスをローテーションします。様々なクライアント・コンテキストが様々な.NETクライアント・ホスト・サーバーにネットワーク接続をランダムにロード・バランシングするので、ランダムな位置から開始すると、複数のクライアントのロード・バランシングが容易になります。

注意:
初期コンテキストで次のようにユーザー名とパスワードを指定することもできます。

paramMap[Constants.Context.SECURITY_PRINCIPAL] = username;
paramMap[Constants.Context.SECURITY_CREDENTIALS] = password;

手順2

JMS接続ファクトリをルックアップします。

IConnectionFactory cf = context.LookupConnectionFactory(this.cfName);

手順3

構成されたJNDI名を使用して、コンテキストでJMS宛先リソースをルックアップします。

IQueue queue = (IQueue)context.LookupDestination(this.queueName);

手順4

接続ファクトリを使用して接続を作成します。.NETクライアント・ホストからJMS接続ホストへのJMS接続が確立されます。接続ホストは、接続ファクトリで構成されているターゲット・リスト内のいずれかのサーバーです。.NETクライアント・ホストと同じでもかまいません。

IConnection connection = cf.CreateConnection();

手順5

コンシューマがメッセージを取得できるように接続を開始します。

connection.Start();

手順6

AUTO_ACKNOWLEDGE確認応答モードを使用してセッションを作成します。

注意:
セッションはスレッド・セーフではありません。プロデューサとコンシューマを同時に実行する必要がある場合は、複数のセッションを使用します。複数のセッションを使用する例については、付録A「JMS .NETクライアント・サンプル・アプリケーション」の非同期サンプルを参照してください。

ISession session = connection.CreateSession(
Constants.SessionMode.AUTO_ACKNOWLEDGE);

手順7

メッセージ・プロデューサを作成して、永続メッセージを送信します。

IMessageProducer producer = session.CreateProducer(queue);

producer.DeliveryMode = Constants.DeliveryMode.PERSISTENT;

ITextMessage sendMessage = session.CreateTextMessage("My q message");

producer.Send(sendMessage);

手順8

メッセージ・コンシューマを作成して、メッセージを受信します。手順6で示したように、セッションがAUTO_ACKNOWLEDGEモードで作成されたため、メッセージはサーバーから自動的に削除されます。

IMessageConsumer consumer = session.CreateConsumer(queue);

IMessage recvMessage = consumer.Receive(500);

手順9

接続を閉じます。接続を閉じると、その子セッション、コンシューマ、およびプロデューサも閉じられます。

connection.Close();

手順10

コンテキストを閉じます。

context.CloseAll();

注意:
context.Close()では、すべてのIConnectionが閉じられるまで、ネットワーク接続を終了しません。context.CloseAll()では、ネットワーク接続と、開いているすべてのIConnectionを閉じます。

JMS .NETクライアント・アプリケーションでの高度な概念の使用

付録A「JMS .NETクライアント・サンプル・アプリケーション」では、C#で記述されたJMS .NETクライアント・アプリケーションの完全な例を紹介し、以下の高度な概念の一部が例示されています。

- 確認応答モードのかわりにローカル・トランザクションを使用。

- メッセージの永続性。詳細は、『Oracle WebLogic Server JMSのプログラミング』の「永続メッセージと非永続メッセージ」を参照してください。

- 確認応答モード。詳細は、『Oracle WebLogic Server JMSのプログラミング』の「非トランザクション・セッション」を参照してください。

- 例外リスナー。詳細は、「ベスト・プラクティス」を参照してください。

- 恒久サブスクリプション。詳細は、『Oracle WebLogic Server JMSのプログラミング』の「恒久サブスクリプションの設定」を参照してください。

相互運用性、セキュリティ、ベスト・プラクティスなど、JMS .NETクライアントのその他の高度な概念を使用する際のガイドラインについては、第4章「プログラミングの考慮事項」を参照してください。

4 プログラミングの考慮事項

この章では、JMS .NETクライアント・アプリケーションを作成する際のプログラミングの考慮事項とベスト・プラクティスを示します。

- WebLogic JMS拡張機能の使用

- WebLogic JMS .NETクライアントの使用に関する制限事項

- 異なる言語環境間でのメッセージの交換

- URLフォーマットの指定

- JMS .NETクライアントでのセキュリティの実装

- ロギングとデバッグの構成

- ソケットとスレッドの動作について

- Javaおよび.NET間のデータ変換

- ベスト・プラクティス

WebLogic JMS拡張機能の使用

表4-1では、このリリースのJMS .NETクライアントでサポートされるWebLogic JMS拡張機能を示します。メッセージングを構成するにはいくつかの方法があります。

- 接続ファクトリでの構成 - この方法では主にデフォルトの構成設定を定義します。

- APIを使用してアプリケーションでプログラム的に構成 - 特定のプログラミング構成で接続ファクトリの構成をオーバーライドできます。

- サーバーでの構成 - 特定の設定で接続ファクトリとプログラム構成の両方をオーバーライドできます。

JMS .NETクライアントとJavaクライアントでは、拡張機能の構成方法や動作に違いがある場合もあります。たとえば、拡張機能によっては、JMS .NET APIを使用してプログラム的に有効にすることはできず、構成を通じてのみ有効にできるものもあります。以下の表にその違いをまとめています。それ以降の節では、必要に応じて、追加の詳細情報を示しています。

表4-1 JMS .NETクライアントでサポートされるWebLogic JMS拡張機能

機能

接続ファクトリで構成可能

サーバーで構成可能

Java API

JMS .NETAPI

説明

分散宛先(共通、重み設定)

詳細は、次を参照してください:

- 『Oracle WebLogic Server JMSのプログラミング』の「分散宛先の使用」

- 『Oracle WebLogic Server JMSの構成と管理』の「分散宛先リソースの構成」

はい

はい

いいえ

いいえ

フロー制御プロデューサ

詳細は、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「JMSサーバーおよび宛先のメッセージのフロー制御」を参照

はい

はい

いいえ

いいえ

割当て条件内でのプロデューサのブロック

詳細は、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「接続ファクトリでの送信タイムアウトの定義」を参照

はい

はい

いいえ

いいえ

WebLogic Serverのリモート・インスタンス用の外部宛先

詳細は、『Oracle WebLogic Server JMSの構成と管理』の「外部サーバー・リソースからサード・パーティJMSプロバイダへのアクセスの構成」を参照

いいえ

はい

いいえ

いいえ

「以前のリリースのWebLogic Serverとの相互運用」を参照してください。

ストア・アンド・フォワード(SAF)インポート済み宛先

詳細は、『Oracle WebLogic Serverストア・アンド・フォワードの構成と管理』の「SAFインポート済宛先」を参照

いいえ

はい

いいえ

いいえ

再配信制限

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージの再配信制限の設定」を参照

いいえ

はい

はい

いいえ

再配信遅延

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージの再配信遅延の設定」を参照

はい

いいえ

はい

いいえ

エラー宛先

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「配信されなかったメッセージに対するエラー宛先の構成」を参照

いいえ

はい

いいえ

いいえ

「WLDestination.getCreateDestinationArgument」

いいえ

いいえ

はい

はい

「確認応答なし」モード

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「NO_ACKNOWLEDGEの使用」を参照

いいえ

いいえ

はい

はい

順序単位

詳細は、次を参照してください:

- 『Oracle WebLogic Server JMSのプログラミング』の「メッセージ順序単位の使用」

- 『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「WebLogic JMSのチューニング」での「順序単位を使用したアプリケーションのチューニング」

はい

はい

はい

はい

「順序単位」を参照してください。

メッセージ配信のスケジューリング

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージ配信時間の設定」を参照してください。

はい

はい

はい

はい

「メッセージ配信時間」を参照してください。

非同期コンシューマのメッセージ最大パイプライン

- 詳細は、『Oracle WebLogic Server JMSのプログラミング』の「非同期のメッセージ・パイプライン」を参照

- 『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「MessageMaximumのチューニング」

はい

いいえ

はい

いいえ

メッセージの圧縮

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージ圧縮」を参照

はい

いいえ

はい

いいえ

「メッセージの圧縮」を参照してください。

割当て

詳細は、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「割当ての定義」を参照

いいえ

はい

いいえ

いいえ

一方向のメッセージ送信

詳細は、『Oracle WebLogic Serverパフォーマンスおよびチューニング』の「一方向メッセージ送信による非永続メッセージングのパフォーマンスの向上」を参照

はい

いいえ

いいえ

いいえ

「一方向のメッセージ送信」を参照してください。

確認応答ポリシー

詳細は、Oracle WebLogic Server管理コンソール・ヘルプの「JMS接続ファクトリ: 構成: クライアント」を参照

はい

いいえ

いいえ

いいえ

メッセージ・プロパティJMSXUserIDとして自動的にuser-idを含む

はい

はい

いいえ

いいえ

「JMSXUserIdとしてのuser-idの使用」を参照してください。

メッセージ・プロパティJMSXDeliveryCountとして配信試行回数を取得

いいえ

いいえ

いいえ

いいえ

「メッセージ配信の試行」を参照してください。

メッセージの圧縮

このリリースでは、JMS .NETクライアントとWebLogic Server上で実行されるJMS .NETクライアント・ホストの間のメッセージ送信において、メッセージの自動圧縮はサポートされていません。ただし、接続ファクトリで圧縮が設定されている場合、.NETクライアント・ホストと宛先の間でのメッセージ圧縮の動作は、Javaクライアントの場合と同じになります。動作は次のとおりです。

- クライアント・ホストと宛先がWebLogic Serverの別々のインスタンス上で実行されている場合、送信されたメッセージはクライアント・ホストにおいて自動的に圧縮されます。

- クライアント・ホストと宛先がWebLogic Serverの同じインスタンス上で実行されている場合、送信されたメッセージは圧縮されません。

圧縮されたメッセージは、.NETクライアントが受信するときに、JMS .NETクライアント・ホストによってサーバー側で解凍されます。

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージ圧縮」を参照

順序単位

JMS .NET APIで順序単位(UOO)を指定する方法はJava APIとは異なります。JMS .NET APIで順序単位を設定するには、希望するUOOを持つメッセージにConstants.MessagePropertyNames.UNIT_OF_ORDER_PROPERTY_NAMEという文字列プロパティを追加します。

詳細は、『Oracle WebLogic Server JMSのプログラミング』の「メッセージ順序単位の使用」を参照

メッセージ配信時間

JMS .NET APIでメッセージ配信時間を指定する方法はJava APIとは異なります。JMS .NET APIでメッセージ配信時間を設定するには、long型のプロパティConstants.MessagePropertyNames.DELIVERY_TIME_PROPERTY_NAMEをメッセージに追加します。この値は、メッセージが配信される将来のミリ秒数です。

一方向のメッセージ送信

接続ファクトリで一方向のメッセージ送信を構成することはできますが、この動作はJMS .NETクライアントでは完全にサポートされていません。一方向送信として送信されたメッセージは、.NETクライアントと.NETクライアント・ホストの間では自動的に双方向送信となり、.NETクライアント・ホストとJMS接続ホストの間では一方向送信になります。

JMSXUserIdとしてのuser-idの使用

受信メッセージに対するシステム生成のメッセージ・プロパティJMSXUserId (オプション)では、元の送信者の資格証明を指定します。このプロパティを有効にするには、宛先、分散宛先、またはテンプレートで[センダー資格証明をアタッチ]属性を構成し、接続ファクトリで「JMSXUserIdをアタッチ」属性を構成します。取得するには、msg.GetStringProperty(Constants.MessagePropertyNames.USER_ID_PROPERTY_NAME)を呼び出します。

メッセージ配信の試行

受信メッセージに対するシステム生成のメッセージ・プロパティJMSXDeliveryCountでは、メッセージ配信の試行回数を指定します。最初の試行は1になります。値を取得するには、msg.GetIntProperty(Constants.MessagePropertyNames.DELIVERY_COUNT_PROPERTY_NAME)を呼び出します。

WebLogic JMS .NETクライアントの使用に関する制限事項

以下の節では、JMS .NETクライアントでサポートされないJMS機能について説明します。

サポートされないJMS 1.1の標準機能

このリリースでは、以下のJMS 1.1の標準機能はサポートされません。

- 一時的な宛先の作成とクローズ(javax.jms.TemporaryQueueおよびjavax.jms.TemporaryTopic)。ただし、受信メッセージのJMSReplyToヘッダーから宛先オブジェクトを取得する場合は、Javaクライアントで作成された一時的な宛先に対してJMS .NETクライアントはメッセージを生成できます。

- javax.jms.QueueRequesterおよびjavax.jms.TopicRequester。(これらのヘルパー・クラスは一時的な宛先に関連しています)。

- キュー・ブラウザ(javax.jms.QueueBrowser)。

- キューおよびトピックのインタフェース(QueueConnectionFactory、TopicConnectionFactory、QueueConnection、TopicConnection、QueueSession、TopicSession)。これらのキューとトピックのインタフェースはJMS 1.0.2のレガシー・インタフェースであり、JMS 1.1の共通インタフェースで置き換えられました。

サポートされないJMS 1.1のオプション機能

このリリースでは、以下のJMS 1.1のオプション機能はサポートされません。

- XAインタフェース(XAConnectionFactory、XAConnection、およびXASession)。

- グローバルXAトランザクションへの参加(「トランザクション」を参照)。

- 接続コンシューマとサーバー・セッション・プール(javax.jms.ConnectionConsumer、ServerSessionPool、およびServerSession)。これらはJava EE MDBで置き換えられたオプション機能であり、WebLogic Java JMSクライアントではサポートされていません。

- MessageProducer.setDisableMessageTimestampメソッド。WebLogic JMS Javaクライアントはこのメソッドを無視します。

サポートされないWebLogic JMS拡張機能

このリリースでは、以下のWebLogic JMS拡張機能はサポートされません。

- SSL

- HTTPトンネリング

- SAFクライアント - 『Oracle WebLogic Serverスタンドアロン・クライアントのプログラミング』の「JMS SAFクライアントによる確実なメッセージ送信」を参照

- マルチキャスト・サブスクライバ - 『WebLogic JMSのプログラミング』の「WebLogic JMSでのマルチキャストの使い方」を参照

- 自動再接続 - 『Oracle WebLogic Server JMSのプログラミング』の「JMSクライアントの自動フェイルオーバー」を参照

- 作業単位(UOW) - .NETクライアントがメッセージにUOWプロパティを設定しようとすると、Weblogic.Messaging.MessageExceptionが生成されます。また、.NETコンシューマは、Javaクライアントによって送信されたデシリアライズ可能なコンテンツを持つUOWメッセージを受信します。この場合、コンシューマは、ObjectMessageのObjectMessage.getObject()メッセージを呼び出すと、MessageFormatExceptionを受け取ります。作業単位はサポートされませんが、より一般的な拡張機能である順序単位は完全にサポートされています。順序単位の詳細は、 「順序単位」を参照してください。

注意:
JMS .NET APIではJMSリソース(トピックやキューなど)をプログラム的に構成するための拡張機能は提供していません。Javaでプログラム的に構成するには、JMX MBeansまたはweblogic.jms.extensions.JMSModuleHelperヘルパー・クラスを使用します。JMSを構成するその他の方法としては、WLSTスクリプトやWebLogic管理コンソールがあります。

トランザクション

このリリースでは、JMS .NETクライアントはJMS仕様での定義にのみ従ってトランザクション・セッションをサポートします。トランザクション・セッションは標準のローカル・トランザクションの機能を提供します。Javaクライアントの場合と同様に、同じクラスタ内の1つまたは複数のWebLogic JMS宛先がトランザクション・セッションのローカル・トランザクションに参加できますが、他のリソースは参加できません(他のクラスタ内のJMSサーバー、データベース、外部JMSプロバイダなど)。

グローバルXAトランザクションはサポートされないため、JMSは.NETトランザクションには参加できません。接続ファクトリのXAの設定は.NETクライアントによって無視されます。JMS .NETクライアントの処理は.NETトランザクションには参加できません。

異なる言語環境間でのメッセージの交換

.NETプロデューサとJavaまたはCコンシューマ、あるいはJavaまたはCプロデューサと.NETコンシューマの間で、以下のJava JMSメッセージ・タイプを交換できます。

- Message

- BytesMessage

- StreamMessage

- MapMessage

- TextMessage

ただし、ObjectMessageタイプは一方の言語から別の言語に送信することはできますが、そのメッセージは同じ言語で記述されない限り、解釈可能になりません。ObjectMessageタイプのプロデューサとコンシューマは同じ言語で記述する必要があります。不一致が生じた場合、つまり、.NET ObjectMessageがJavaコンシューマで受信されたり、Java ObjectMessageが.NETコンシューマで受信されたりした場合、message.getObject()はMessageFormatExceptionを送出します。

URLフォーマットの指定

Provider_URLには、以下のフォーマットを使用して、カンマで区切って複数のアドレスを格納できます。

t3://address [,address]...

特定のアドレスで複数のポート範囲を指定できます。

複数のアドレスを指定する構文は次のとおりです。

address = hostlist : portlist

説明:

hostlist = hostname [, hostname]...
portlist = portrange [+ portrange]...
portrange = port [- port]

port -portを使用してポート範囲を指定し、+ (プラス記号)を使用して複数のポート範囲を区切ります。

表4-2に、URLフォーマットの例を示します。

表4-2 URLフォーマットの例

フォーマット

可能なフォーマット

t3://hostA:7001
t3://hostA,hostB:7001,hostC:7002

t3://hostA:7001,hostB:7001,hostC:7002

t3://hostA:7001+7005+7007,hostB:7001

t3://hostA:7001,hostA:7005,hostA:7007,
hostB:7001

t3://hostA:7001-7003+7005+7007,hostB:8001

t3://hostA:7001,hostA:7002,hostA:7003,
hostA:7005,hostA:7007,hostB:8001

DNS別名ホスト名の使用

複数のホストに展開されるDNS別名ホスト名を指定することもできます。たとえば、DNS別名myclusterがhost1,host2に解決される場合、URL t3://mycluster:7001はアドレス・リストt3://host1:7001,host2:7001に展開されます。このURLを指定して作成されたコンテキストでは常に、host1にアクセスできない場合はhost2を使って再試行します。DNS別名は通常、ネットワーク管理者が構成します。

JMS .NETクライアントでのセキュリティの実装

JMS .NETクライアントを作成する場合は以下のセキュリティの考慮事項に注意する必要があります。

- サーバー上のセキュアなJNDIおよびJMSリソースにアクセスするために、JMS .NETクライアント・アプリケーションは以下のようにユーザー名とパスワードを提示できます。

- ContextFactory.CreateContext()を使用して、サーバーへの初期コンテキストを確立します。サーバー上のセキュアなJNDIおよびJMSリソースにアクセスするための認証では、初期コンテキストの作成時に提示された資格証明が使用されます。

- IConnectionFactory.createConnection()メソッドを使用して接続を作成します。この場合、接続の作成時に提示された資格証明が、初期コンテキストで提示された資格証明をオーバーライドします。たとえば、初期コンテキストでユーザーFredが提示され、接続の作成時にユーザーTonyが提示された場合、セキュアなJMSリソースにアクセスするための認証では、ユーザーTonyの資格証明が使用されます。

注意:
どちらのインスタンスでもパスワードは暗号化されます。リソースがセキュアでない場合は、ユーザー名とパスワードは省略可能です。

警告:
ユーザー名とパスワードは保護され、パスワードは暗号化されますが、高度なユーザーや侵入者によって保護メカニズムが破られる可能性があります。ユーザー名とパスワードを提示する場合には、ネットワーク接続を保護するようにしてください。

- .NETクライアントの認証は、セキュアなリソースを呼び出すJMSオブジェクトに関連付けられています。つまり、JMSオブジェクトの資格証明は親のJMSコンテキストから継承されるか、接続の作成時に資格証明が提示された場合には接続オーバーライドから継承されます。この点は、資格証明が現在のスレッドに関連付けられているJavaクライアントのセキュリティとは異なります。

- このリリースのJMS .NETクライアントではSSLはサポートされません。そのため、オペレーティング・システムが提供するネットワーク・サービスを保護するほかに、ネットワーク接続を保護することが重要です。詳細は、『Oracle WebLogic Server本番環境の保護』の「プロダクション環境のセキュリティの確保」に記載されている「ネットワーク接続のセキュリティ」を参照してください。

- Javaクライアントと同様に、JMS .NETクライアントはメッセージ・レベルの暗号化をサポートしません。

- 暗号化されていない通信を使用すると、アプリケーション・トラフィックの傍受が可能になります(http://www.owasp.org/index.php/Sniffing_application_traffic_attackを参照)。このようなリスクを受け入れるか、攻撃を防御するためにファイアウォールを使用するなどの対策を取る必要があります。

- 管理ポートが構成された場合は、SSLトラフィックのみを受け入れ、ポートを経由するすべての接続は管理者権限を必要とします。また、管理ポートが構成された場合、他のすべてのポートは管理者権限を持つ接続を拒否します。このリリースのJMS .NETクライアントではSSLがサポートされていないため、管理ポートが構成されている場合でも、管理者権限を持つユーザーをサポートできません。

ロギングとデバッグの構成

サーバー側の転送と、WebLogic Server上で実行される.NETクライアント・ホストにおいて、基本的なロギングとデバッグを使用できます。

サーバー側

サーバー側でデバッグを有効にするには、以下のコマンドを使用します。

-Dweblogic.debug.DebugJMSDotNetT3Server=true
-Dweblogic.debug.Debug.JMSDotNetProxy=true

クライアント側

クライアント側のロギングとデバッグを有効にして制御するには、アプリケーション構成ファイル内の様々な構成設定を使用します。生成されたビルド・ファイルに対するアプリケーション構成ファイルの名前はyourapplicationname.exe.configです。yourapplicationnameはメッセージング・クライアントを実行するアプリケーションの名前です。

例4-1では、ロギングとデバッグを構成するためにアプリケーション構成ファイルに追加する必要のあるXMLコンテンツを示します。その後の節で、各種の設定の詳細について補足します。すでにyourapplicationname.exe.configファイルがある場合は、以下のリストで示すXMLコンテンツをファイルに追加してください。既存のファイルがない場合は、ファイルを作成して、yourapplicationname.exeファイルと同じディレクトリに格納してください。

注意:
Visual Studioを使用している場合は、例4-1に示すロギングとデバッグの設定をApp.configファイルに追加する必要があります。Visual Studio環境でC#プロジェクトにApp.configファイルを追加するには、Microsoft Webサイトhttp://msdn.microsoft.com/en-us/library/ms184658.aspxの指示に従ってください。

例4-1 yourapplicationname.exe.configファイルのXMLファイル・コンテンツ

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- To forward log output to a file, please uncomment the following line, and replace the file name with the desired one -->
<!--- <add key="weblogic.JMSDotNet.debugConfig.LogFileName" value="c:\test\MyLogFile.log" /> -->

<!-- To prevent log messages from displaying to the console, use the value 'false' -->
<!-- <add key="weblogic.debug.JMSDotNet.config.IsLogToConsole" value="false" /> -->
</appSettings>
<system.diagnostics>
<switches>
<!-- Please set the switch value as desired for logging to each Category -->
<!-- value for Off=0, Error=1, Warning=2, Info=3, Verbose=4    -->

<!-- if "AllLogger" is enabled (no zero for the value), every individual category is set to the same level as the AllLogger,
no matter how individual category's value is set -->
<add name="weblogic.debug.JMSDotNet.All" value="0" />
<add name="weblogic.debug.JMSDotNet.Socket" value="0" />
<add name="weblogic.debug.JMSDotNet.T3" value="0" />
<add name="weblogic.debug.JMSDotNet.Transport" value="0" />
<add name="weblogic.debug.JMSDotNet.PhysicalMsg" value="0" />
<add name="weblogic.debug.JMSDotNet.LogicalMsg" value="0" />
</switches>
</system.diagnostics>
</configuration>

メッセージ出力

ログ・メッセージをコンソールに出力するか、ファイルに保存するかを指定するには、表4-3に示すように、<appSettings>要素を使用します。

表4-3 appSettingsの値

キー

値

設定

weblogic.JMSDotNet.debugConfig.LogFileName

String

ログ・ファイルの絶対パスとファイル名(c:\test\MyLogFile.logなど)。

注意: デフォルトのログ・ファイル・サイズ制限は500KB。ログ・ファイルがこのサイズに達するたびに、サーバーはログ・ファイルの名前を変更し、新しいMyLogFile.logを作成して新しいメッセージを格納します。デフォルトでは、ローテーションされるログ・ファイルには、MyLogFile.log.0、MyLogFile.log.1、MyLogFile.log.2、...のように作成順に番号が付けられます。MyLogFile.log.0に最新のログ・メッセージが格納されます。

weblogic.JMSDotNet.debugConfig.IsLogToConsole

Boolean

- True - ログ・メッセージをコンソールに表示します。

- False - ログ・メッセージをコンソールに表示しません。

ログのカテゴリとレベル

クライアント側のロギングは以下のカテゴリに分類されます。

- Socket

- T3

- Transport

- PhysicalMsg

- LogicalMsg

- All (上記の個々のカテゴリのすべてを表す)

カテゴリごとに次のロギング・レベルを指定できます。

Off(0), Error(1), Warning(2), Info(3), Verbose(4)

Allカテゴリの重要度レベルは個々のカテゴリの設定をオーバーライドすることに注意してください。

ソケットとスレッドの動作について

WebLogic JMS .NETクライアントは他のタイプのWebLogicクライアントと同じWebLogic Server T3ポートを共有します。.NETクライアントはContextFactoryクラスを使用してIContext初期コンテキストを作成するときに、サーバー上のT3対応のポートを参照するURLを指定します。要求されたネットワーク接続を処理するために、1つのソケット・ペアが暗黙的に作成されます。ソケット・ペアはクライアント上の1つのソケットと、WebLogic Server JMS .NETクライアント・ホスト上のもう1つのソケットから成ります。.NETコンテキストから取得されたJMSオブジェクトに対するJMS操作はすべて、コンテキストの暗黙的なネットワーク接続を通じてルーティングされます。

同じ.NET CLR上で2つのIContext初期コンテキスト・インスタンスが、同じWebLogic Server JMS .NETクライアント・ホストに同時に接続した場合は、2つのネットワーク接続が作成されます。各ネットワーク接続はそれぞれ1組のソケット(サーバー側ソケットとクライアント側ソケット)を保持します。したがって、2つのネットワーク接続が作成された場合は、CLRクライアント上で2つのソケットが作成され、JMS .NETクライアント・ホストとして機能するWebLogic Server上でも2つのソケットが作成されます。この動作はWebLogic Javaクライアントとは対照的です。WebLogic Javaクライアントでは、リモートのJVMへのネットワーク接続が重複していれば自動的に検出し、重複した接続を閉じます。かわりに、特定のリモートJVMとの間のすべてのトラフィックを、1つのネットワーク接続上で暗黙的に多重化します。

JMS .NETクライアントのサーバー側ソケットは、他のタイプのWebLogicクライアントと同じWebLogic Serverソケット・リーダー・マルチプレクサ・スレッド・プールによって提供されます。JMS .NETクライアントのリクエストを処理する場合、ソケット・リーダー・マルチプレクサ・スレッド・プールは受信リクエストをソケットから読み取り、WebLogic Serverのデフォルト・スレッド・プールに作業をディスパッチします。デフォルト・スレッド・プールでは、リクエストを処理してクライアントに応答を返送します。

JMS .NETクライアントでは、ネットワーク接続ごとに(つまり、各IContext初期コンテキスト・インスタンスに対して)新しい内部スレッドが自動的に作成されます。この専用のスレッドがクライアントで受信するすべてのデータを読み取り、関連する作業をCLRスレッド・プールにディスパッチします。つまり、.NETクライアント・アプリケーションの非同期メッセージ・イベント・ハンドラはCLRスレッド・プール内で実行されます。

注意:
CLRスレッド・プールは.NET FrameworkのSystem.Threading.ThreadPoolクラスで提供されます。1つのプロセスにつき1つのスレッド・プールが存在します。スレッド・プールのデフォルト・サイズは1プロセッサ当たり25スレッドであるが、ThreadPool.SetMaxThreadsメソッドを使用すると、スレッド・プール内のスレッド数を変更できます。スレッド・プール内の各スレッドはデフォルトのスタック・サイズを使用し、デフォルトの優先順位で実行されます。詳細は、Microsoft .NET FrameworkのドキュメントでSystem.Threading.ThreadPoolクラスを参照してください。

JMS .NETアプリケーションで同時に多数の初期コンテキストが作成され、そのすべてが同じWebLogic Server .NETクライアント・ホストに接続する場合は、1つの共有初期コンテキストを使用するようにアプリケーションを変更すると、パフォーマンスを改善できます。共有コンテキストを使用すると、クライアントは1つのネットワーク接続のみを作成するようになります。

Javaおよび.NET間のデータ変換

- エンディアンの変換

- 符号付きバイトと符号なしバイトの変換

- バイト配列の転送

- 時間の変換

エンディアンの変換

Javaと.NETではプリミティブ型を格納するために異なる形式のバイト順序を使用しています。

- Microsoft Windows .NETはリトル・エンディアン(下位順序)形式を使用

- Javaはビッグ・エンディアン(上位順序)形式を使用

Javaと.NETの相互運用性をサポートするために、データはビッグ・エンディアン形式を使用してネットワーク上で転送されます。.NETアプリケーションがJMS .NET APIを使用してプリミティブの読み書きを行うときに、データは必要に応じて自動的に、ビッグ・エンディアンとリトル・エンディアンの間で変換されます。たとえば、JMS .NET APIのBytesMessage.WriteIntを使用する場合、データは常にビッグ・エンディアンで格納され、Java APIとJMS .NET APIの両方のバイト・メッセージ読込み整数メソッドを使用して読み込むことができます。

JMS .NET APIを使用してプリミティブを渡すかわりに、未加工のバイト配列を使用してプリミティブ・データを転送する特殊なアプリケーションの場合は、Javaとやり取りする際にバイト形式をビッグ・エンディアンに手動で変換する必要があります。アプリケーションでエンディアンの手動変換を実行する必要がある場合は、JMS .NETクライアント・ライブラリで提供されているユーティリティ・クラスWebLogic.Messaging.Transport.Util.EndianConvertorの以下のヘルパー・メソッドを使用できます。

public static char SwitchEndian(char x)
public static short SwitchEndian(short x)
public static int SwitchEndian(int x)
public static long SwitchEndian(long x)
public static ushort SwitchEndian(ushort x)
public static uint SwitchEndian(uint x)
public static ulong SwitchEndian(ulong x)
public static double SwitchEndian(double x)
public static float SwitchEndian(float x)
public static byte[] SwitchEndian(byte[] x)

たとえば、未加工のバイト配列との間でプリミティブの読み書きを行う標準の.NETクラスSystem.IO.BinaryReaderとSystem.IO.BinaryWriterでは、リトル・エンディアンを使用します。以下のコードの抜粋は、.NETのバイト配列との間で整数を格納および取得する方法を示しています。

binaryWriter.WriteInt(EndianConverter.SwitchEndian(i))
i=EndianConverter.SwitchEndian(binaryReader.ReadInt())

符号付きバイトと符号なしバイトの変換

Javaプリミティブ・データ型のそれぞれに同じ名前と定義のC#データ型が対応していますが、byteデータ型については例外があります。以下の表に、C#とJavaで符号付きバイトと符号なしバイトに使用される異なる名前を示します。

表4-4 C#とJavaのバイト・プリミティブ・データ型

C#

Java

説明

byte

N/A

符号なしバイト

sbyte

byte

符号付きバイト

表4-4に示すように、Microsoft .NETでは、byte (符号なしバイト)とsbyte (符号付きバイト)の両方をプリミティブ・データ型としてサポートしていますが、Javaでは、byte (符号付きバイト)のみを直接のプリミティブ型としてサポートしています。どちらの言語の標準規約でもbyteデータ型の使用が規定されていますが、.NETでは符号なしバイトを表し、Javaでは符号付きバイトを表します。

.NETとJavaの間の相互運用性を確保するため、JMS .NETクライアントではバイトの読み書きに符号付きバイトのみを使用するようになっています。バイト値が127以下の場合は符号付きバイトと符号なしバイトの間に違いはありません。値が127以下の符号なしバイトはsbyteとして格納されます。ただし、.NETクライアントで127より大きな値の符号なしバイトを符号付きバイトに格納する必要があった場合は、その値を符号付きバイトから符号なしバイトに変換する必要が生じます。以下のサンプルでは、符号なしバイトを符号付きバイトとして読み書きするために使用できる変換メソッドを例示します。

- C#でのバイト変換
符号なしバイト値の255を次のように符号付きバイトとして渡すことができます。

- byte unsignedByteValue = 255;

- sbyte signedByteValue = unchecked ( (sbyte)unsignedByteValue ); //変換後の符号付き値 =-1

同様に、以下のメソッドを使用して、符号付きバイト値を符号なしバイト値に変換できます。

- sbyte signedByteValue = -1;

- byte unsignedByteValue = unchecked ( (byte)signedByteValue ); //変換後の符号なし値 =255

- Javaでのバイト変換
次のように、符号なしバイトは符号付きバイトとして読み込んでから、符号なしバイト値に変換できます。

- byte signedByteValue = -1;

- int unsignedByteValue = 0xFF & signedByteValue; //変換後の符号付き値 = 255

符号なしバイト値は次のように書き込むことができます。

- Int unsignedByteValue = 255;

- byte signedByteValue = 0xFF & unsignedByteValue; //変換後の符号付き値 =-1

JMS .NET APIでは1つのバイトを符号付きバイトとしてのみ格納できます。JMS .NET APIを使用してsbyteをshort、int、long、またはstringとして取得する場合、値は符号なしバイトではなくsbyteとして扱われます。たとえば、符号なしバイト値255をmessage.SetByteProperty("myvalue", unchecked( (sbyte)((byte)255) ))を使用して格納した場合、message.GetByteProperty("myvalue")またはmessage.GetShortProperty("myvalue")を呼び出すと「-1」が返されます。

バイト配列の転送

JMS .NETクライアントからWebLogic JMSにバイト配列を転送する場合、すべてのバイト配列(byte[])はそのまま渡されます(つまり、符号なしから符号付きへの変換はありません)。そのため、変換でデータが失われることはありません。

時間の変換

WebLogic JMS .NET APIでは、.NETの規約ではなくJavaの規約を使用して日付と時間を表現します。WebLogic.Messaging.IMessageメッセージ・インタフェースのJMSTimestampおよびJMSExpiration属性はlong型であり、Javaプログラミング言語で規定されているミリ秒の絶対時間を格納します。Javaのミリ秒の絶対時間の値は、協定世界時(UTC)の1970年1月1日午前0時から特定の時間までの差異をミリ秒単位で測定したものです。

以下の例では、.NET時間とJavaのミリ秒の絶対時間の値の変換方法を示します。

例4-2 現在の.NET時間をJavaのミリ秒時間に変換するC#サンプル・コード

// Example:  C# code for converting the current .NET time to Java millisecond time
DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
DateTime utcNow = DateTime.UtcNow;
long timeInMillis = (utcNow.Ticks - baseTime.Ticks)/10000;
Console.WriteLine(timeInMillis);

例4-3 Javaのミリ秒時間を.NET時間に変換するC#サンプル・コード

// Example:  C# code for converting Java millisecond time to .NET time
DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
long utcTimeTicks = (timeInMillis * 10000) + baseTime.Ticks;
DateTime utcTime = new DateTime(utcTimeTicks, DateTimeKind.Utc);
Console.WriteLine(utcTime);
Console.WriteLine(utcTime.ToLocalTime());

ベスト・プラクティス

以下の節では、JMS .NETクライアント・アプリケーションを作成する際のプログラミングのベスト・プラクティスを示します。

- アイドル接続が失敗した場合にアプリケーションが対応する必要がある場合は、IConnectionを使用して接続例外リスナーを常に登録します。.NETクライアントとWebLogic .NETクライアント・ホストの間や、WebLogicホストとJMS接続ホストの間で通信エラーが発生した場合は、接続例外リスナーに非同期に通知されます。アプリケーションでは接続例外リスナー・コールバックを実装して、開いているすべてのリソースを閉じてから、定期的に再接続を試行することもできます。

- パフォーマンスを向上させるには、複数の.NETクライアント・スレッドで1つのコンテキストを共有して、1つのソケットを使用するようにします。詳細は、「ソケットとスレッドの動作について」を参照してください。1つのコンテキストで1つのソケットが作成され、コンテキストを閉じるとそのソケットも閉じられる点に留意してください。

- コンテキスト、接続、セッション、プロデューサ、宛先、接続ファクトリなど、頻繁にアクセスするJMSリソースはキャッシュして再利用します。これらのリソースを作成してクローズすると、CPUとネットワーク帯域幅がかなり消費されます。

- close()メソッドを除いて、JMSセッションとその子リソースはスレッド・セーフではありません。たとえば、プロデューサとコンシューマを同じセッションで作成した場合は、あるスレッドでプロデューサのsend()メソッドを呼び出し、並行して別のスレッドでコンシューマのreceive()メソッドを呼び出さないようにしてください。もう1つ例を挙げると、非同期コンシューマがあるセッションの任意のスレッドではclose()以外のメソッドを呼び出さないでください。メッセージの到着とコールバックの呼出しが同時に行われる可能性があるためです。

- クラスタ内の複数のJMS .NETクライアント・ホスト・サーバーにわたってJMS .NETクライアントをロード・バランシングする場合は、DNS別名かカンマ区切りのアドレスを使用します。このリリースのJMS .NETクライアントでは、Javaクライアントで暗黙的に提供されるようなクラスタの自動ロード・バランシングはサポートしていません。

A JMS .NETクライアント・サンプル・アプリケーション

この章では、WebLogic JMS .NET APIの基本的な機能を含む、C#で記述された.NETクライアント・サンプル・プログラムを示します。APIの詳細は、.NETクライアント用のWebLogicメッセージングAPIリファレンスのドキュメントを参照してください。

例A-1 MessagingSample.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

using WebLogic.Messaging;

/// <summary> Demonstrate the WebLogic JMS .NET API.
/// <para>
/// This command line program connects to WebLogic JMS and performs
/// queue and topic messaging operations.  It is supported with
/// versions 10g Release 3 and later.  To compile the program,
/// link it with "WebLogic.Messaging.dll".   For usage information,
/// run the program with "-help" as a parameter.
/// </para>
/// <para>
/// Copyright 1996,2008, Oracle and/or its affiliates. All rights reserved.
/// </para>
/// </summary>

public class MessagingSample
{
private static string NL = Environment.NewLine;

private string host      = "localhost";
private int    port      = 7001;

private string cfName    = "weblogic.jms.ConnectionFactory";
private string queueName = "jms.queue.TestQueue1";
private string topicName = "jms.topic.TestTopic1";

private static string USAGE =
"Usage: " + Environment.GetCommandLineArgs()[0] + NL +
"          [-host <hostname>] [-port <portnum>] " + NL +
"          [-cf <connection factory JNDI name>] " + NL +
"          [-queue <queue JNDI name>] [-topic <topic JNDI name>]";

public static void Main(string[] args)
{
try {
MessagingSample ms = new MessagingSample();

// override defaults with command line arguments
if (!ms.ParseCommandLine(args)) return;

ms.DemoSyncQueueReceiveWithAutoAcknowledge();

ms.DemoAsyncNondurableTopicConsumerAutoAcknowledge();

ms.DemoSyncTopicDurableSubscriberClientAcknowledge();

} catch (Exception e) {
Console.WriteLine(e);
}
}

private void DemoSyncQueueReceiveWithAutoAcknowledge()
{
Console.WriteLine(
NL + "-- DemoSyncQueueReceiveWithAutoAcknowledge -- " + NL);

// ------------------------------------------------
// Make a network connection to WebLogic and login:
// ------------------------------------------------

IDictionary<string, Object> paramMap = new Dictionary<string, Object>();

paramMap[Constants.Context.PROVIDER_URL] =
"t3://" + this.host + ":" + this.port;

IContext context = ContextFactory.CreateContext(paramMap);

try {
// -------------------------------------
// Look up our resources in the context:
// -------------------------------------

IConnectionFactory cf = context.LookupConnectionFactory(this.cfName);

IQueue queue = (IQueue)context.LookupDestination(this.queueName);

// -------------------------------------------------
// Create a connection using the connection factory:
// -------------------------------------------------

IConnection connection = cf.CreateConnection();

// -----------------------------------------------------------------
// Start the connection in order to allow receivers to get messages:
// -----------------------------------------------------------------

connection.Start();

// -----------------
// Create a session:
// -----------------
// IMPORTANT:  Sessions are not thread-safe.   Use multiple sessions
// if you need to run producers and/or consumers concurrently. For
// more information, see the asynchronous consumer example below.
//

ISession session = connection.CreateSession(
Constants.SessionMode.AUTO_ACKNOWLEDGE);

// ------------------------------------------------
// Create a producer and send a persistent message:
// ------------------------------------------------

IMessageProducer producer = session.CreateProducer(queue);

producer.DeliveryMode = Constants.DeliveryMode.PERSISTENT;

ITextMessage sendMessage = session.CreateTextMessage("My q message");

producer.Send(sendMessage);

PrintMessage("Sent Message:", sendMessage);

// ----------------------------------------
// Create a consumer and receive a message:
// ----------------------------------------
// The message will automatically be deleted from the server as the
// consumer's session was created in AUTO_ACKNOWLEDGE mode.
//

IMessageConsumer consumer = session.CreateConsumer(queue);

IMessage recvMessage = consumer.Receive(500);

PrintMessage("Received Message:", recvMessage);

// ------------------------------------------------------------------
// Close the connection.   Note that closing a connection also closes
// its child sessions, consumers, and producers.
// ------------------------------------------------------------------

connection.Close();

} finally {

// ------------------------------------------------------------------
// Close the context.  The CloseAll method closes the network
// connection and all related open connections, sessions, producers,
// and consumers.
// ------------------------------------------------------------------

context.CloseAll();
}
}

// Implement a MessageEventHandler delegate.  It will receive
// asynchronously delivered messages.

public void OnMessage(IMessageConsumer consumer, MessageEventArgs args) {
PrintMessage("Received Message Asynchronously:", args.Message);

// -----------------------------------------------------------------
// If the consumer's session is CLIENT_ACKNOWLEDGE, remember to
// call args.Message.Acknowledge() to prevent the message from
// getting redelivered, or consumer.Session.Recover() to force redelivery.
// Similarly, if the consumer's session is TRANSACTED, remember to
// call consumer.Session.Commit() to prevent the message from
// getting redeliverd, or consumer.Session.Rollback() to force redeivery.
}

private void DemoAsyncNondurableTopicConsumerAutoAcknowledge()
{
Console.WriteLine(
NL + "-- DemoAsyncNondurableTopicConsumerAutoAcknowledge -- " + NL);

// ------------------------------------------------
// Make a network connection to WebLogic and login:
// ------------------------------------------------

IDictionary<string, Object> paramMap = new Dictionary<string, Object>();

paramMap[Constants.Context.PROVIDER_URL] =
"t3://" + this.host + ":" + this.port;

IContext context = ContextFactory.CreateContext(paramMap);

try {
// -------------------------------------
// Look up our resources in the context:
// -------------------------------------

IConnectionFactory cf = context.LookupConnectionFactory(this.cfName);

ITopic topic = (ITopic)context.LookupDestination(this.topicName);

// --------------------------------------------------------------
// Create a connection using the connection factory and start it:
// --------------------------------------------------------------

IConnection connection = cf.CreateConnection();

// -----------------------------------------------------------------
// Start the connection in order to allow receivers to get messages:
// -----------------------------------------------------------------

connection.Start();

// ------------------------------------------
// Create the asynchronous consumer delegate.
// ------------------------------------------
// Create a session and a consumer; also designate a delegate
// that listens for messages that arrive asynchronously.
//
// Unlike queue consumers, topic consumers must be created
// *before* a message is sent in order to receive the message!
//
// IMPORTANT:  Sessions are not thread-safe.   We use multiple sessions
// in order to run the producer and async consumer concurrently.  The
// consumer session and any of its producers and consumers
// can no longer be used outside of the OnMessage
// callback once OnMessage is designated as its event handler, as
// messages for the event handler may arrive in another thread.
//

ISession consumerSession = connection.CreateSession(
Constants.SessionMode.AUTO_ACKNOWLEDGE);

IMessageConsumer consumer = consumerSession.CreateConsumer(topic);

consumer.Message += new MessageEventHandler(this.OnMessage);

// -------------
// Send Message:
// -------------
// Create a producer and send a non-persistent message.  Note
// that even if the message were sent as persistent, it would be
// automatically downgraded to non-persistent, as there are only
// non-durable consumers subscribing to the topic.
//

ISession producerSession = connection.CreateSession(
Constants.SessionMode.AUTO_ACKNOWLEDGE);

IMessageProducer producer = producerSession.CreateProducer(topic);

producer.DeliveryMode = Constants.DeliveryMode.NON_PERSISTENT;

ITextMessage sendMessage = producerSession.CreateTextMessage(
"My topic message");

producer.Send(sendMessage);

PrintMessage("Sent Message:", sendMessage);

// -----------------
// Wait for Message:
// -----------------
// Sleep for one second to allow the delegate time to receive and
// automatically acknowledge the message.  The delegate will print
// to the console when it receives the message.
//

Thread.Sleep(1000);

// ---------
// Clean Up:
// ---------
// We could just call connection.Close(), which would close
// the connection's sessions, etc, or we could even just
// call context.CloseAll(), but we want to demonstrate closing each
// individual resource.
//

producer.Close();
consumer.Close();
producerSession.Close();
consumerSession.Close();
connection.Close();

} finally {

// -------------------------------------------------------------
// Close the context.  The CloseAll method closes the network
// connection and any open JMS connections, sessions, producers,
// or consumers.
// -------------------------------------------------------------

context.CloseAll();
}
}

private void DemoSyncTopicDurableSubscriberClientAcknowledge() {

Console.WriteLine(
NL + "-- DemoSyncTopicDurableSubscriberClientAcknowledge -- " + NL);

// ------------------------------------------------
// Make a network connection to WebLogic and login:
// ------------------------------------------------

IDictionary<string, Object> paramMap = new Dictionary<string, Object>();

paramMap[Constants.Context.PROVIDER_URL] =
"t3://" + this.host + ":" + this.port;

IContext context = ContextFactory.CreateContext(paramMap);

try {
// -------------------------------------
// Look up our resources in the context:
// -------------------------------------

IConnectionFactory cf = context.LookupConnectionFactory(this.cfName);

ITopic topic = (ITopic)context.LookupDestination(this.topicName);

// -------------------------------------------------
// Create a connection using the connection factory:
// -------------------------------------------------

IConnection connection = cf.CreateConnection();

// --------------------------------------------
// Assign a unique client-id to the connection:
// --------------------------------------------
// Durable subscribers must use a connection with an assigned
// client-id.   Only one connection with a given client-id
// can exist in a cluster at the same time.  An alternative
// to using the API is to configure a client-id via connection
// factory configuration.

connection.ClientID = "MyConnectionID";

// -----------------------------------------------------------------
// Start the connection in order to allow consumers to get messages:
// -----------------------------------------------------------------

connection.Start();

// -----------------
// Create a session:
// -----------------
// IMPORTANT:  Sessions are not thread-safe.   Use multiple sessions
// if you need to run producers and/or consumers concurrently. For
// more information, see the asynchronous consumer example above.
//

ISession session = connection.CreateSession(
Constants.SessionMode.CLIENT_ACKNOWLEDGE);

// -----------------------------------------------
// Create a durable subscription and its consumer.
// -----------------------------------------------
// Only one consumer at a time can attach to the durable
// subscription for connection ID "MyConnectionID" and
// subscription ID "MySubscriberID.
//
// Unlike queue consumers, topic consumers must be created
// *before* a message is sent in order to receive the message!
//

IMessageConsumer consumer = session.CreateDurableSubscriber(
topic, "MySubscriberID");

// ------------------------------------------------
// Create a producer and send a persistent message:
// ------------------------------------------------

IMessageProducer producer = session.CreateProducer(topic);

producer.DeliveryMode = Constants.DeliveryMode.PERSISTENT;

ITextMessage sendMessage = session.CreateTextMessage("My durable message");

producer.Send(sendMessage);

PrintMessage("Sent Message To Durable Subscriber:", sendMessage);

// ----------------------------------------------------
// Demonstrate closing and re-creating the consumer.
//
// The new consumer will implicitly connect to the durable
// subscription created above, as we specify the same
// connection id and subscription id.
//
// A durable subscription continues to exist and accumulate
// new messages when it has no consumer, and even keeps
// its persistent messages in the event of a client or server
// crash and restart.
//
// Non-durable subscriptions and their messages cease to
// exist when they are closed, or when their host server
// shuts down or crashes.
// ----------------------------------------------------

consumer.Close();

consumer = session.CreateDurableSubscriber(
topic, "MySubscriberID");

// -------------------------------------------------------------------
// Demonstrate client acknowledge.  Get the message, force
// it to redeliver, get it again, and then finally delete the message.
// -------------------------------------------------------------------
// In client ack mode "recover()" forces message redelivery, while
// "acknowledge()" deletes the message.  If the client application
// crashes or closes without acknowledging a message, it will be
// redelivered.

ITextMessage recvMessage = (ITextMessage)consumer.Receive(500);

PrintMessage("Durable Subscriber Received Message:", recvMessage);

session.Recover();

recvMessage = (ITextMessage)consumer.Receive(500);

PrintMessage("Durable Subscriber Received Message Again:", recvMessage);

recvMessage.Acknowledge();

// ------------------------------------------------------------
// Delete the durable subscription, otherwise it would continue
// to exist after the demo exits.
// ------------------------------------------------------------
//

consumer.Close();  // closes consumer, but doesn't delete subscription

session.Unsubscribe("MySubscriberID"); // deletes subscription

// ------------------------------------------------------------------
// Close the connection.   Note that closing a connection also closes
// its child sessions, consumers, and producers.
// ------------------------------------------------------------------

connection.Close();

} finally {

// ------------------------------------------------------------------
// Close the context.  The CloseAll method closes the network
// connection and all related open connections, sessions, producers,
// and consumers.
// ------------------------------------------------------------------

context.CloseAll();
}
}

private void PrintMessage(String header, IMessage msg) {
string msgtext;

if (msg is ITextMessage)
msgtext = " Text=" + ((ITextMessage)msg).Text + NL;
else
msgtext = " The message is not an ITextMessage";

string dcProp =
Constants.MessagePropertyNames.DELIVERY_COUNT_PROPERTY_NAME;

System.Console.WriteLine(
header + NL +
" JMSMessageID=" + msg.JMSMessageID + NL +
" JMSRedelivered=" + msg.JMSRedelivered + NL +
" " + dcProp + "=" + msg.GetObjectProperty(dcProp) + NL +
msgtext);
}

private bool ParseCommandLine(string[] args)
{
int i = 0;
try {
for(i = 0; i < args.Length; i++) {
if (args[i].Equals("-host")) {
host = args[++i];
continue;
}
if (args[i].Equals("-port")) {
port = Convert.ToInt32(args[++i]);
continue;
}
if (args[i].Equals("-cf")) {
cfName = args[++i];
continue;
}
if (args[i].Equals("-queue")) {
queueName = args[++i];
continue;
}
if (args[i].Equals("-topic")) {
topicName = args[++i];
continue;
}
if (args[i].Equals("-help") || args[i].Equals("-?")) {
Console.WriteLine(USAGE);
return false;
}
Console.WriteLine("Unrecognized parameter '" + args[i] + "'.");
Console.WriteLine(USAGE);
return false;
}
} catch (System.IndexOutOfRangeException) {
Console.WriteLine(
"Missing argument for " + args[i - 1] + "."
);
Console.WriteLine(USAGE);
return false;
} catch (FormatException) {
Console.WriteLine(
"Invalid argument '" + args[i] + "' for " + args[i - 1] + "."
);
Console.WriteLine(USAGE);
return false;
}
Console.WriteLine(
"WebLogic JMS .NET Client Demo " + NL +
NL +
"Settings: " + NL +
"  host     = " + host + NL +
"  port     = " + port + NL +
"  cf       = " + cfName + NL +
"  queue    = " + queueName + NL +
"  topic    = " + topicName + NL
);
return true;
}
}

Copyright © 2007, 2011, Oracle and/or its affiliates. All rights reserved.