7km以上走ると、ヒザに来るhamatairaです。
GeneXusでメッセージキューが使えるようだったので、
試してみました。
メッセージキューが使えると、他のアプリケーションと連携して動作したり、
GeneXusのプロシージャで、Submitで動かしているものとメッセージをやり取りして
終了させるなどの処理ができるようになります。
開発環境は、
・Windows7 Professional Service Pack 1
・GeneXus Ev2 U3
今回は、C#とIISの環境でナレッジを作成しました。
まずは、下準備。
■MSMQ(Microsoft メッセージキュー)を使えるようにします。
・「コントロールパネル」→「プログラムと機能」の中の
「Windowsの機能の有効化または無効化」
・「Microsoft メッセージキュー(MSMQ)サーバー」の中の設定を下図のように設定します。
※今回は、メッセージのやり取りのみ行うので、これだけでOK。
・サービスが起動しているかを確認するには、
「コントロールパネル」→「管理ツール」→「サービス」で確認できます。
「Message Queuing」が動いていればOKです。
■プライベートキューの作成を行います。
・「コントロールパネル」→「管理ツール」→「コンピュータの管理」
・「専用キュー」を右クリック→「新規作成」→「専用キュー」
・ダイアログに、キューの名前を入力し、OKボタン押下。
※作成したキューのプロパティで、「ラベル」の値を控えておいてください。
後述の「web.config」ファイルを追記する部分で使用します。
■キューのアクセス権の設定
・先ほど作ったプライベートキューのアクセス権を設定します。
今回は、Everyoneを使用します。
・設定の内容は、以下のものにチェックを入れます。
「メッセージの受信」
「メッセージのピーク」
「メッセージの送信」
■「web.config」ファイルに使用するメッセージキューの記述を追加。
・「C:\Models\GeneXusのナレッジ名\CSharpModel\web」フォルダにある、
「web.config」ファイルの「<appSettings>」の下に、メッセージキューの記述を追加します。
※「client.exe.config」に記述しても、メッセージキューがうまく動作しないので、
気を付けてください。
先ほど作成したメッセージキューの名前が「queueProvider」だった場合、
記述例は、以下のようになります。
[記述例]
<add key=”Queue-queueProvider” value=”コンピュータ名\private$\queueProvider” />
・「value=”コンピュータ名\private$\queueProvider”」の部分についての確認方法は、
先ほどの「コンピュータの管理」で作成したプライベートキューを
右クリック→「プロパティ」で確認することができます。(「ラベル」の項目)
下準備、長いですよね。
ようやくGeneXusの登場です。
■実装例の概要
・送信側
メッセージキューへ、停止要求のメッセージを送信します。
停止要求送信後、停止要求に対する応答を受信します。
・受信側
一定回数回るプロシージャをコールします。
今回は、1秒間Sleepを行い、30回回るものを用意しました。
プロシージャ内では、メッセージキューを使用してメッセージの受信処理を行います。
停止要求のメッセージを受信したら、ループを抜けて終了します。
停止要求のメッセージを受信しなかった場合は、30回ループが回り終わったら、
処理が終了となります。
■送信部分の実装例
・各変数の型は、以下になります。
&SndQueue :Queue
&SndConResult :Numeric
&SndMessage :QueueMessage
&SndMsgResult :VarChar
&RcvMessage :QueueMessage
&SleepResult :Numeric
&RcvMessageStr:VarChar
・実装例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
//メッセージ送信 Do while true //キューの設定 &SndQueue.Provider = "queueProvider" //接続 &SndConResult = &SndQueue.Connect() If &SndConResult = 0 //0:接続失敗, 1:接続成功 //接続失敗 Msg('送信キューの接続失敗') Exit Else //接続成功 Msg('送信キューの接続成功') Endif //送信メッセージの作成 &SndMessage.Text = "StopReq" &SndMessage.Priority = 7 //送信 &SndMsgResult = &SndQueue.Send(&SndMessage) If &SndMsgResult = "" //送信失敗 Msg("送信失敗") Else //送信成功 Msg("送信成功(" + Trim(&SndMsgResult) + "): " + &SndMessage.Text.ToString()) //応答待機 Msg("応答待機中") &SleepResult = Sleep(2) //応答メッセージの受信 For &RcvMessage in &SndQueue &RcvMessageStr = &RcvMessage.Text.ToString() Msg("メッセージ受信:" + &RcvMessageStr) Exit Endfor Endif Exit Enddo //切断 &SndQueue.Disconnect() |
■受信部分の実装例
・各変数の型は、以下になります。
&RcvQueue :Queue
&RcvConResult:Numeric
&RcvMessage :QueueMessage
&Cnt:Numeric
&SleepResult:Numeric
&RcvMessageStr:VarChar
&SndMessage:QueueMessage
&SndMsgResult:VarChar
・実装例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
//停止メッセージ受信 Do while True //キューの設定 &RcvQueue.Provider = "queueProvider" //接続 &RcvConResult = &RcvQueue.Connect() If &RcvConResult = 0 //0:接続失敗, 1:接続成功 //接続失敗 Msg('受信キューの接続失敗') Exit Else //接続成功 Msg('受信キューの接続成功') Endif //30秒間のループ &Cnt = 0 Do while &Cnt < 30 &SleepResult = Sleep(1) //メッセージの受信 For &RcvMessage in &RcvQueue &RcvMessageStr = Trim(&RcvMessage.Text.ToString()) Msg(&RcvMessageStr) Exit Endfor If Trim(&RcvMessageStr) = "StopReq" //停止メッセージ受信 Msg("停止メッセージ受信のため、終了") //応答メッセージ送信 &SndMessage.Text = "StopAck" &SndMessage.Priority = 7 &SndMsgResult = &RcvQueue.Send(&SndMessage) If &SndMsgResult = "" //送信失敗 Msg("応答メッセージ送信失敗") Else //送信成功 Msg("応答メッセージ送信成功") Endif Exit Else //停止メッセージ未受信 Msg("&Cnt = " + &Cnt.ToString()) Endif &Cnt += 1 Enddo Exit Enddo //切断 &RcvQueue.Disconnect() |
受信の場合はキューに接続して、For~inでメッセージを展開する形になります。
送信の方で、Priority(優先度)を7にしていましたが、若い数字(1~6)を使用すると、
優先度の設定値が、若い数字の順に受信されるようでした。
■実行結果
・停止要求を受信しなかった場合(受信側)
・停止要求を受信した場合
・停止要求を送信した後の送信側
別プロセスで動いていたプログラムが、メッセージを受信をきっかけに、
メインループを抜けて、終了したことが確認できました。
以上が、GeneXusでのメッセージキューを使用したメッセージのお試しです。
ほとんど、MSMQの設定の説明になってしまいましたが、
何かのお役にたてて頂ければうれしいです。