MSMQとPowerShell

この記事は以前にdevslife.comで紹介したものです。

かみさんも息子も床に就き、自分だけが起きているそんな静かな時間が好きだ。こんな時間に技術に関するブログを書くのがいい。

.NET FrameworkにはSystem.Messagingという名前空間があってその中にはMSMQと直接通信できるクラスが存在する。MSMQとは何か。以下マイクロソフトのサイトから抜粋

MSMQ (Microsoft Message Queuing) は、Microsoft WindowsR のコンポーネントの 1 つであり、高い信頼性を持つメッセージ機能を実現する最新テクノロジの成果です。MSMQ を使用すると、高性能な従来のキューイング インフラストラクチャと API で必要とされる信頼性が得られます。

なんともマーケティング用の文章なので初心者の方だったら頭の周りにクエスチョンマークが百個ぐらい出てくることだろう。もうちょっと分かりやすく砕いて言うと、異システム間のメッセージのやり取りを可能にするものと言っていいと思う。ってこれも分かりにくいか・・・MSMQの詳しいことについてはこちらで読んでもらうことにして・・・

とりあえずMSMQにメッセージを書き込むコードから。

[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$queuePath = "FormatName:Direct=OS:ServerName\private$\QueueName"
$mq = new-object System.Messaging.MessageQueue($queuePath)
$mq.Send("Hello World")

System.MessagingはデフォルトではPowerShellのメモリに読み込まれていないので一行目のような作業が必要になる。後は見てのとおり単にMessegeQueueクラスを使って文字通りメッセージを送るだけ。今回の例ではStringの型をSendに入れているがこれは他のオブジェクトでもなんら差し支えない。

では、MSMQからメッセージを受け取るにはどうしたらいいだろうか。これは実際にPowerShellでやってみて少々手こずったが、 次のようにすると読み込むことができる。

[System.Reflection.Assembly]::LoadWithPartialName("System.Messaging")
$mq = New-Object System.Messaging.MessageQueue("ServerName\private$\QueueName")
$formatter = new-object System.Messaging.XmlMessageFormatter([string])
$mq.Formatter = $formatter
$expiration = New-Object System.TimeSpan(0, 0, 10) #5 seconds
$msg = $mq.Receive($expiration)

$msg.Body

上のコードを少々説明することにしよう。

一行目は前の例と同じでSystem.MessagingのアセンブリをPowerShell上に読み込んで使えるようにするものだ。メッセージを読み込む場合にもMessageQueueクラスを使うのには変わりないが、そのほかに今度はformatterが必要になってくる。つまりこれは MSMQに存在するSerializeされたオブジェクトをDeserializeするために必要なのである。たとえそれがStringみたいな基本的な型であってもだ。

またメッセージを読み込む場合はExpiration、つまり読み込み時の期限切れの時間幅を決めておいたほうがいいだろう。それがないと Receiveメッソドを実行したときにMSMQが全くない場合は永遠に待ち続けることになる。でも待っている時間幅を決めておくと、例えば5秒以内に MSMQにメッセージが入ってこなかった場合はExceptionを投げてくれる。それをちゃんと捕まえて処理してやれば何の問題もないはずだ。

とたったの10行ぐらいで、簡単にPowerShellでMSMQへの読み書きができてしまうのだ。

コメント

  1. けろ-みお より:

    このMSMQは、BizTalk Server に実装してやるともっと幅が広がるんですが、
    残念ながら、今、BizTalk Server は、PowerShellに対応していないので、
    使える場所が限定されてしまっているのが残念です・・・
    BizTalk Server も SQL Server や IIS みたくPowerShellを実装すれば
    良いのに・・・って思います。

タイトルとURLをコピーしました