マネージド・コードからの COM+ メッセージ・キューの利用 ~ MSMQ 入門
MQ の概要
メッセージキュー (MQ) は、メッセージの処理を非同期に行います。
MQ は留守番電話に似た仕組みと考えられます。クライアントは、キューに対してメッセージを "録音" します。サーバー側では、キューからメッセージを取り出して "再生" します。 アイデアは新しい物ではありません。
上述の留守番電話の例で言うと、"録音" は Recorder を通して Queue Manager に対して行います。Queue Manager はクライアントとサーバー間の Queue 同士でのメッセージ交換を受け持ちます。サーバー側では、Queue Manager からメッセージを取り出し再生します。キューを監視するコンポーネントは、Listener といい "再生" は Player が行います。
アーキテクチャ
最低でもサーバー上にメッセージを処理するメッセージキューが必要です。 サーバーキューだけではなく、クライアントもキューを持つことができます。 クライアントとサーバー間の接続がある場合は直ちにクライアントのキューは空になり、サーバー上のキューにメッセージが置かれます。
メッセージキューでの登場人物(コンポーネント)は以下の通りです。
- Recorder
クライアントからの出力を受け取り、ひとつ以上のメッセージを作成し、ローカルキューまたはプロキシーにそのメッセージを送信する。 - Listener
サーバーキューをみて、それをキューから取り出し、Player にメッセージを渡す。 - Player
メッセージを受け取る。メッセージの処理などを行うコンポーネントもここに含まれる。
MQ のアーキテクチャ
キューの種類
キューは大きく分けて2種類あります。
- Application
プログラムから自動的に、または手動で作成されるキュー。通常アプリケーションが使うキューはこちら。 - System
Dead letter queues = 特定の時間内に処理できなかったメッセージが格納される
Journal queues = アプリケーション、MSMQ またはシステムイベントによって使用される。
使い方シナリオ
- すべて手動
- 手動でキューを作成
- プログラムから指定したキューにメッセージを置く
- 明示的にメッセージを取りに行く。
- キューを手動で作成。キューに置かれたことだけを自動的に追跡する
- 手動でキューを作成
- プログラムで指定したキューにメッセージを配信
- MSMQのトリガーを使って、条件に応じ、COM+アプリケーションのメソッドを呼び出す
- キューの作成も自動化
- Queued Component を作成する。COM+の属性として Queuing するよう指定するとキューが作成される。
- 呼び出し側は COM+ コンポーネントのメソッドを呼び出すだけ。
実行例: メッセージキュー作成・メッセージの作成・読み取り、全て手動の場合
MSMQ の有効化
この資料は Windows Vista Ultimate Edition 英語版で動作試験しています。
上の設定で (マイ) コンピュータの [管理] にて Messaging Queuing が表示されることを確認してください。
キューの作成
メッセージ・レコーダの作成
以下の内容を、recorder1.cs として保存します。
using System; using System.Messaging; namespace MyTest { class Recorder1 { public static void Main() { // // メッセージキューオブジェクトの作成 // MessageQueue TestMQ; TestMQ = new System.Messaging.MessageQueue(); TestMQ.Path = "<コンピュータ名>\\private$\\MyTestQueue1"; TestMQ.Formatter = new XmlMessageFormatter (new Type[] {typeof(String)}); TestMQ.MessageReadPropertyFilter.Priority = true; // // メッセージの作成 // System.Messaging.Message msg; msg = new System.Messaging.Message(); msg.Label = "Hello"; msg.Body = "This is a sample program."; msg.Priority = (MessagePriority) 0; // // メッセージキューにメッセージを置く // TestMQ.Send (msg); } } }
以下の内容を makefile として保存します。
CSC = csc.exe TARGETNAME=recorder1 SOURCE_FILE=recorder1.cs REF= OUTDIR=.\chk all: "$(OUTDIR)\$(TARGETNAME).exe" "$(OUTDIR)" : if not exist "$(OUTDIR)" mkdir "$(OUTDIR)" CSC_OPT=\ /nologo\ /target:exe\ /out:$(OUTDIR)\$(TARGETNAME).exe\ /doc:$(OUTDIR)\$(TARGETNAME).xml\ /debug+\ /debug:full\ /optimize-\ /warn:4 $(OUTDIR)\$(TARGETNAME).exe: "$(OUTDIR)" $(SOURCE_FILE) $(CSC) $(CSC_OPT) $(REF) $(SOURCE_FILE)
上記、recorder1.cs と makefile を同じディレクトリに保存してください。 nmake のある、Visual Studio Command Prompt 等から nmake を実行してビルドしてください。
> nmake -a
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
if not exist ".\chk" mkdir ".\chk"
csc.exe /nologo /target:exe /out:.\chk\recorder1.exe
/doc:.\chk\recorder1.xml
/debug+ /debug:full /optimize- /warn:4 recorder1.cs
>
メッセージ・プレイヤーの作成
以下の内容を、player1.cs として保存します。
using System; using System.Messaging; namespace MyTest { class Player1 { public static void Main() { // // メッセージキューオブジェクトの作成 // MessageQueue TestMQ; TestMQ = new System.Messaging.MessageQueue(); TestMQ.Path = "<コンピュータ名>\\private$\\MyTestQueue1"; TestMQ.Formatter = new XmlMessageFormatter (new Type[] {typeof(String)}); TestMQ.MessageReadPropertyFilter.Priority = true; // // メッセージの取得 // System.Messaging.Message msg; try { msg = TestMQ.Receive (new TimeSpan(5)); } catch (MessageQueueException e) { Console.WriteLine ("No message to retrieve. {0}", e.Message); return; } Console.WriteLine ("Label: {0}\nBody: {1}", msg.Label, msg.Body); } } }
以下の内容を makefile として保存します。
CSC = csc.exe TARGETNAME=player1 SOURCE_FILE=player1.cs REF= OUTDIR=.\chk all: "$(OUTDIR)\$(TARGETNAME).exe" "$(OUTDIR)" : if not exist "$(OUTDIR)" mkdir "$(OUTDIR)" CSC_OPT=\ /nologo\ /target:exe\ /out:$(OUTDIR)\$(TARGETNAME).exe\ /doc:$(OUTDIR)\$(TARGETNAME).xml\ /debug+\ /debug:full\ /optimize-\ /warn:4 $(OUTDIR)\$(TARGETNAME).exe: "$(OUTDIR)" $(SOURCE_FILE) $(CSC) $(CSC_OPT) $(REF) $(SOURCE_FILE)
上記、player1.cs と makefile を同じディレクトリに保存してください。 nmake のある、Visual Studio Command Prompt 等から nmake を実行してビルドしてください。
> nmake -a
Microsoft (R) Program Maintenance Utility Version 9.00.30729.01
Copyright (C) Microsoft Corporation. All rights reserved.
if not exist ".\chk" mkdir ".\chk"
csc.exe /nologo /target:exe /out:.\chk\player1.exe
/doc:.\chk\player1.xml
/debug+ /debug:full /optimize- /warn:4 player1.cs
>
動作確認
- 上記で作成した recorder1.exe を実行する。
すると上記で作成した、プライベートキュー MyTestQueue1 にメッセージがポストされたことが確認できる。
メッセージのプロパティを見ると、確かにレコーダー・プログラム recorder1.exe から送信したメッセージであることが確認できる。
- 上記で作成した player1.exe を実行する。
> player1.exe Label: Hello Body: This is a sample program. >
確かにキューのメッセージが表示された。また、キューの画面を更新すると、キューからメッセージがなくなっていることも確認できる。
以上、この資料では C# から MQ を利用する方法について説明しました。