BLOGTIMES
2010/10/02

Ruby から MSMQ を使う

  ruby  mom 
このエントリーをはてなブックマークに追加

MSMQでRubyからメッセージ受送信できる方法を調べてみたのでメモ。

ちょっと調べてみたところ、RubyにはMSMQ向けのライブラリはないようなのでWIN32OLE経由で呼び出だすことにします。よって、ホストがWindowsでない場合、以下のサンプルスクリプトは動作しません。MSMQのCOMのインタフェイスについてはMSDNの「メッセージ キュー COM コンポーネント」で調べることができます。

プログラミング自体はそんなに難しくはありませんが、ハマりやすいポイントとしてはキューがトランザクションキューかそうでないかで、受送信方法が異なることでしょうか。トランザクションキューにするか否かの設定はキュー作成時に行う必要があり、作成後は変更することができないので、うっかりキューの種類にそぐわない方法で受送信を行おうとするとうまくいきません。

非トランザクションキューの受送信

msmq_nontr_get.rbの方は永久ループでメッセージを取得するようになっているので、msmq_nontr_get.rbを起動させてから、msmq_nontr_put.rbを起動するとメッセージが1つずつ取得される様子を見ることができます。

msmq_nontr_put.rb

#!ruby -Ks require 'win32ole' module MSMQ; end WIN32OLE::const_load(WIN32OLE.new('MSMQ.MSMQQueueInfo'), MSMQ) QUEUE_NAME = 'test' dest = WIN32OLE.new('MSMQ.MSMQDestination') dest.PathName = '.\private$\\' + QUEUE_NAME msg = WIN32OLE.new('MSMQ.MSMQMessage') msg.Label = "FooLabel" msg.Body = "BarBody" msg.Priority = 1 # Put message into non-transactional queue msg.Send(dest)

msmq_nontr_get.rb

#!ruby -Ks require 'win32ole' module MSMQ; end WIN32OLE::const_load(WIN32OLE.new('MSMQ.MSMQQueueInfo'), MSMQ) QUEUE_NAME = 'test' # Get message from non-transactional queue mqi = WIN32OLE.new('MSMQ.MSMQQueueInfo') mqi.PathName = '.\private$\\' + QUEUE_NAME q = mqi.Open(MSMQ::MQ_RECEIVE_ACCESS,MSMQ::MQ_DENY_NONE) while true msg = q.Receive puts "Recieved!: Label:#{msg.Label}, Body:#{msg.Body}, Priority:#{msg.Priority}" end

トランザクションキューの受送信

こちらはキューがトランザクションをサポートする場合です。「づめメモ  MSMQのトランザクション機能を試すRubyスクリプト」を参考にさせていただきました。こちらも上記と同様に、msmq_tr_get.rbを起動させてからmsmq_tr_put.rbを起動することで1つずつ処理がされていく様子を見ることができます。

msmq_tr_put.rb

#!ruby -Ks require 'win32ole' module MSMQ; end WIN32OLE::const_load(WIN32OLE.new('MSMQ.MSMQQueueInfo'), MSMQ) QUEUE_NAME = 'test_tr' dest = WIN32OLE.new('MSMQ.MSMQDestination') dest.PathName = '.\private$\\' + QUEUE_NAME msg = WIN32OLE.new('MSMQ.MSMQMessage') msg.Label = "FooLabel" msg.Body = "BarBody" msg.Priority = 1 # Put message into transactional queue ( w/o MSMQTransaction ) msg.Send("DestinationQueue"=> dest,"Transaction"=>MSMQ::MQ_SINGLE_MESSAGE) # Put message into transactional queue ( w/ MSMQTransaction ) trd = WIN32OLE.new("msmq.MSMQTransactionDispenser") tr = trd.begintransaction msg.Send("DestinationQueue"=> dest,"Transaction"=>tr) tr.commit

msmq_tr_get.rb

#!ruby -Ks require 'win32ole' module MSMQ; end WIN32OLE::const_load(WIN32OLE.new('MSMQ.MSMQQueueInfo'), MSMQ) QUEUE_NAME = 'test_tr' # Get message from transactional queue ( w/ MSMQTransaction ) mqi = WIN32OLE.new('MSMQ.MSMQQueueInfo') mqi.PathName = '.\private$\\' + QUEUE_NAME q = mqi.Open(MSMQ::MQ_RECEIVE_ACCESS,MSMQ::MQ_DENY_NONE) trd = WIN32OLE.new("msmq.MSMQTransactionDispenser") while true tr = trd.begintransaction msg = q.Receive("Transaction"=>tr) puts "Recieved!: Label:#{msg.Label}, Body:#{msg.Body}, Priority:#{msg.Priority}" tr.commit end

    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3833
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン