以下の環境下でMSMQによる通信を構築しようとしてはまったので、備忘録。
- 送信側Windows XP、受信側Windows 7
- 両マシンともWork group状態での接続、つまりActive Directory無し
- C#でWindows.Messagingクラスライブラリを使用する
Active Directoryが無いので受信側ではプライベートキュー private$/abcを作成。このマシンローカルではメッセージの送受信が可能なことを確認。
送信プログラムをWindows XPマシンに移し実行。送信先キューにはDIRECT=TCP:192.168.137.1¥private$¥abcを指定。ここで192.168.137.1は受信PCのIPアドレス。System.Messaging.MessageQueueクラスを使うので実際の指定はFormatName:DIRECT=TCP:192.168.137.1¥private$¥abc。
[トラブル その1 ] 送信側のコントロールパネルからOutgoing queuesを見ると、未送信のキューがたまっているが、Statusはいつまで経ってもWaiting to connect。つまり受信側マシンに接続できない状態。
- 受信側マシンのコマンドプロンプトからnetstat -aと打ち込み、ポート1801がLISTENINGになっているかを調べる。なっていない場合は何かしらの理由で受信側がキューを受け取る状態に無い。
- ポート1801がLISTENINGの場合、送信側マシンからこのポートにtelnet接続してみる。接続拒否されるなら受信側マシンでファイアーウォールなどが邪魔をしている可能性が高い。
- 受信側マシンがインターネットに直接接続されているとWindowsが判断した場合、セキュリティー上の理由でHTTP接続しか受け付けないようになる。この場合の対策としては下記のいずれか。
- HTTP接続に切り替える。両マシンにWindows機能の追加からMSMQにHTTPサポートをつけてインストール。送信側から指定する送信先はDIRECT=http://192.168.137.1/msmq/private$/abc
- Control Panel→ Computer Management (コンピューターの管理) → Message Queuing (メッセージキュー。Private QueuesやOutgoing Queuesフォルダを格納しているところ)を右クリック → プロパティ。Server Security (サーバーセキュリティ)タブからEnable hardened MSMQ modeで始まる項目からチェックをはずす(上図)。
私の場合はポート1801がLISTENINGになっていなかったのですが、設定をいじっているうちにLISTENINGになってしまい、どの操作で改善したのか分からず。これでStatusがConnectedになりましたが、いやなパターンだ(-_-;)
[トラブル その2 ] 送信後、送信側のOutgoing queuesは空っぽであり送信されたっぽいが、受信側には受け取ったキューが見当たらない。
- 送信側のネットワークケーブルを引き抜きキューを送信。Outgoing queuesにたまっているのを確認後、ネットワークを復活させるとOutgoing queuesが空になるので送信されている模様。
- 受信マシン上でコントロールパネルからイベントビューアを開き、Applications and Services Logs¥Microsoft¥Windows¥MSMQ¥End2Endを右クリックでプロパティ。Enable loggingにチェックを入れて、再度送信マシンから送信。
- 正常ならメッセージが来た(Message came over network)とメッセージが受信キューに格納されたの2つがログに残るはず。前者しかない場合、コントロールパネルのComputer Management(コンピューターの管理)から対象の受信キュー(今回ならprivate$/abc)を右クリック→プロパティ、 セキュリティータブでANONYMOUS LOGONユーザーを追加、Send Message (メッセージの送信)に許可を与える (下図)
私の環境ではこれでやっとメッセージがネットワーク経由で送信されました。
[ 参考 ]
- Why does MSMQ "lock" your outgoing queue? (MSDN Blogs)
- Where have my MSMQ messages gone? (MSDN Blogs)
[2016/10/4 追記] HTTP接続でもWaiting to connectの場合、ファイアーウォールが原因の場合があります。外部のマシンからブラウザで受信側マシンにアクセスしてIISのページが表示されなければ可能性大。参考: Windows 7 で IIS を立ち上げた際、Windows ファイアウォールの許可されたプログラムに追加しないと外部デバイスからアクセスできません (ゆめとちぼーとげんじつと)
[2024/3/22 追記] サーバーをマシン名で指定している場合、IPアドレス(10.80.0.123など)指定に変えると通る場合あるようです。受信Windowsのマシン名とDNS上のマシン名を比較チェックをするんだとか。HaProxyとかロードバランサを間に挟んでハマりました。参考: Can't send a MSMQ message to the second DNS name of a server (Stack Exchange)
Comments