![]() ![]() ![]() ![]() |
以下の節では、JMS .NET クライアント アプリケーションを作成する際のプログラミングの考慮事項とベスト プラクティスを示します。
表 4-1 では、このリリースの JMS .NET クライアントでサポートされる WebLogic JMS 拡張機能を示します。メッセージングをコンフィグレーションするにはいくつかの方法があります。
JMS .NET クライアントと Java クライアントでは、拡張機能のコンフィグレーション方法や動作に違いがある場合もあります。たとえば、拡張機能によっては、JMS .NET API を使用してプログラム的に有効にすることはできず、コンフィグレーションを通じてのみ有効にできるものもあります。以下の表にその違いをまとめています。それ以降の節では、必要に応じて、追加の詳細情報を示しています。
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
|
|||||
このリリースでは、JMS .NET クライアントと WebLogic Server 上で実行される JMS .NET クライアント ホストの間のメッセージ送信において、メッセージの自動圧縮はサポートされていません。ただし、接続ファクトリで圧縮が設定されている場合、.NET クライアント ホストと送り先の間でのメッセージ圧縮の動作は、Java クライアントの場合と同じになります。動作は次のとおりです。
圧縮されたメッセージは、.NET クライアントが受信するときに、JMS .NET クライアント ホストによってサーバ サイドで解凍されます。
詳細については、『WebLogic JMS プログラマーズ ガイド』の「メッセージの圧縮」を参照してください。
JMS .NET API で順序単位 (UOO) を指定する方法は Java API とは異なります。JMS .NET API で順序単位を設定するには、希望する UOO を持つメッセージに Constants.MessagePropertyNames.UNIT_OF_ORDER_PROPERTY_NAME
という文字列プロパティを追加します。
詳細については、『WebLogic JMS プログラマーズ ガイド』の「メッセージ順序単位の使用」を参照してください。
JMS .NET API でメッセージ配信時間を指定する方法は Java API とは異なります。JMS .NET API でメッセージ配信時間を設定するには、long
型のプロパティ Constants.MessagePropertyNames.DELIVERY_TIME_PROPERTY_NAME
をメッセージに追加します。この値は、メッセージが配信される将来のミリ秒数です。
接続ファクトリで一方向のメッセージ送信をコンフィグレーションすることはできますが、この動作は JMS .NET クライアントでは完全にサポートされていません。一方向送信として送信されたメッセージは、.NET クライアントと .NET クライアント ホストの間では自動的に双方向送信となり、.NET クライアント ホストと JMS 接続ホストの間では一方向送信になります。
受信メッセージに対するシステム生成のメッセージ プロパティ JMSXUserId
(省略可能) では、元の送信者の資格を指定します。このプロパティを有効にするには、送り先、分散送り先、またはテンプレートで [センダ資格をアタッチ] 属性をコンフィグレーションし、接続ファクトリで [JMSX ユーザ ID をアタッチ] 属性をコンフィグレーションします。取得するには、msg.GetStringProperty(Constants.MessagePropertyNames.USER_ID_PROPERTY_NAME)
を呼び出します。
受信メッセージに対するシステム生成のメッセージ プロパティ JMSXDeliveryCount
では、メッセージ配信の試行回数を指定します。最初の試行は 1 になります。値を取得するには、msg.GetIntProperty(Constants.MessagePropertyNames.DELIVERY_COUNT_PROPERTY_NAME)
を呼び出します。
以下の節では、JMS .NET クライアントでサポートされない JMS 機能について説明します。
このリリースでは、以下の 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 のオプション機能はサポートされません。
XAConnectionFactory
、XAConnection
、および XASession
)。javax.jms.ConnectionConsumer
、ServerSessionPool
、および ServerSession
)。これらは Java EE MDB で置き換えられたオプション機能であり、WebLogic Java JMS クライアントではサポートされていません。MessageProducer.setDisableMessageTimestamp
メソッド。WebLogic JMS Java クライアントはこのメソッドを無視します。
このリリースでは、以下の WebLogic JMS 拡張機能はサポートされません。
Weblogic.Messaging.MessageException
が生成されます。また、.NET コンシューマは、Java クライアントによって送信されたデシリアライズ可能なコンテンツを持つ UOW メッセージを受信します。この場合、コンシューマは、ObjectMessage
の ObjectMessage.getObject()
メッセージを呼び出すと、MessageFormatException
を受け取ります。作業単位はサポートされませんが、より一般的な拡張機能である順序単位は完全にサポートされています。順序単位の詳細については、「順序単位」を参照してください。注意 : | JMS .NET API では JMS リソース (トピックやキューなど) をプログラム的にコンフィグレーションするための拡張機能は提供していません。Java でプログラム的にコンフィグレーションするには、JMX MBean または weblogic.jms.extensions.JMSModuleHelper ヘルパー クラスを使用します。JMS をコンフィグレーションするその他の方法としては、WLST スクリプトや WebLogic Administration Console があります。 |
このリリースでは、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 メッセージ タイプを交換できます。
ただし、ObjectMessage
タイプは一方の言語から別の言語に送信することはできますが、そのメッセージは同じ言語で記述されない限り、解釈可能になりません。ObjectMessage
タイプのプロデューサとコンシューマは同じ言語で記述する必要があります。不一致が生じた場合、つまり、.NET ObjectMessage
が Java コンシューマで受信されたり、Java ObjectMessage
が .NET コンシューマで受信されたりした場合、message.getObject()
は MessageFormatException
を送出します。
Provider_URL
には、以下のフォーマットを使用して、カンマで区切って複数のアドレスを格納できます。
t3://address
[,address
]...
port
-port
を使用してポート範囲を指定し、+
(プラス記号) を使用して複数のポート範囲を区切ります。
表 4-2 に、URL フォーマットの例を示します。
複数のホストに展開される DNS エリアス ホスト名を指定することもできます。たとえば、DNS エリアス mycluster
が host1,host2
に解決される場合、URL t3://mycluster:7001
はアドレス リスト t3://host1:7001,host2:7001
に展開されます。この URL を指定して作成されたコンテキストでは常に、host1
にアクセスできない場合は host2
を使って再試行します。DNS エリアスは通常、ネットワーク管理者がコンフィグレーションします。
JMS .NET クライアントを作成する場合は以下のセキュリティの考慮事項に注意する必要があります。
ContextFactory.CreateContext()
を使用して、サーバへの初期コンテキストを確立する。サーバ上のセキュアな JNDI および JMS リソースにアクセスするための認証では、初期コンテキストの作成時に提示された資格が使用されます。IConnectionFactory.createConnection()
メソッドを使用して接続を作成する。この場合、接続の作成時に提示された資格が、初期コンテキストで提示された資格をオーバーライドします。たとえば、初期コンテキストでユーザ Fred
が提示され、接続の作成時にユーザ Tony
が提示された場合、セキュアな JMS リソースにアクセスするための認証では、ユーザ Tony
の資格が使用されます。注意 : | どちらのインスタンスでもパスワードは暗号化されます。リソースがセキュアでない場合は、ユーザ名とパスワードは省略可能です。 |
警告 : | ユーザ名とパスワードは保護され、パスワードは暗号化されますが、高度なユーザや侵入者によって保護メカニズムが破られる可能性があります。ユーザ名とパスワードを提示する場合には、ネットワーク接続を保護するようにしてください。 |
サーバ サイドの転送と、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 の指示に従ってください。 |
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- ログ出力をファイルに転送するには、次の行をコメント解除し、ファイル名を希望する名前で置き換える -->
<!--- <add key="weblogic.JMSDotNet.debugConfig.LogFileName" value="c:\test\MyLogFile.log" /> -->
<!-- ログ メッセージがコンソールに表示されないようにするには、値「false」を使用する -->
<!-- <add key="weblogic.debug.JMSDotNet.config.IsLogToConsole" value="false" /> -->
</appSettings>
<system.diagnostics>
<switches>
<!-- カテゴリごとに、ロギングに必要なスイッチ値を設定する -->
<!-- 値は Off=0、Error=1、Warning=2、Info=3、Verbose=4 -->
<!-- 「AllLogger」を有効にした場合 (ゼロ以外の値を設定した場合) は、個々のカテゴリに値を設定したとしても、
すべてのカテゴリが AllLogger と同じレベルに設定される -->
<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>
要素を使用します。
クライアント サイドのロギングは以下のカテゴリに分類されます。
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 の相互運用性をサポートするために、データはビッグ エンディアン形式を使用してネットワーク上で転送されます。.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 に示すように、Microsoft .NET では byte
(符号なしバイト) と sbyte
(符号付きバイト) の両方をプリミティブ データ型としてサポートしていますが、Java では byte
(符号付きバイト) のみを直接のプリミティブ型としてサポートしています。どちらの言語の標準規約でも byte
データ型の使用が規定されていますが、.NET では符号なしバイトを表し、Java では符号付きバイトを表します。
.NET と Java の間の相互運用性を確保するため、JMS .NET クライアントではバイトの読み書きに符号付きバイトのみを使用するようになっています。バイト値が 127 以下の場合は符号付きバイトと符号なしバイトの間に違いはありません。値が 127 以下の符号なしバイトは sbyte
として格納されます。ただし、.NET クライアントで 127 より大きな値の符号なしバイトを符号付きバイトに格納する必要があった場合は、その値を符号付きバイトから符号なしバイトに変換する必要が生じます。以下のサンプルでは、符号なしバイトを符号付きバイトとして読み書きするために使用できる変換メソッドを例示します。
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 のミリ秒の絶対時間の値の変換方法を示します。
// 例 : 現在の .NET 時間を Java のミリ秒時間に変換する C# コード
DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);
DateTime utcNow = DateTime.UtcNow;
long timeInMillis = (utcNow.Ticks - baseTime.Ticks)/10000;
Console.WriteLine(timeInMillis);
// 例 : Java のミリ秒時間を .NET 時間に変換する C# コード
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 接続ホストの間で通信エラーが発生した場合は、接続例外リスナに非同期に通知されます。アプリケーションでは接続例外リスナ コールバックを実装して、開いているすべてのリソースを閉じてから、定期的に再接続を試行することもできます。close()
メソッドを除いて、JMS セッションとその子リソースはスレッド セーフではない。たとえば、プロデューサとコンシューマを同じセッションで作成した場合は、あるスレッドでプロデューサの send()
メソッドを呼び出し、並行して別のスレッドでコンシューマの receive()
メソッドを呼び出さないようにしてください。もう 1 つ例を挙げると、非同期コンシューマがあるセッションの任意のスレッドでは close()
以外のメソッドを呼び出さないでください。メッセージの到着とコールバックの呼び出しが同時に行われる可能性があるためです。
![]() ![]() ![]() |