はじめに
以前、RabbitMQを通してメッセージを手動で送信する方法を解説しました。
RabbitMQのManagementプラグインには手動でメッセージを作成して送信する機能があるので、これを利用すれば普段は何かしら別のコンポーネントからメッセージをPublishしなければ動作を試せないという問題を解決できます。
さて、それでは、普段はこのメッセージキューの中をどのようなメッセージが流れているのでしょうか?
前回はメッセージキューに送信するメッセージを指定しましたが、あの形式で送信すればメッセージが正しく処理されるとなぜわかるのでしょうか?
今回は、この疑問を解決し、以前のメッセージ送信の方法の記事と合わせて、メッセージキューの受信側だけで動作を試せるようにしたいと思います。
前提
「RabbitMQのManagementプラグインからメッセージを流してみた」の記事で解説したサンプルが作成できている
メッセージの読み出し方
まずは前回作成したProgram.csの中身に変更を加えます。
using System;
using MassTransit;
namespace massTransitEx
{
public class Program
{
public static void Main(string[] args)
{
var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
{
var host = sbc.Host(new Uri("rabbitmq://localhost"), h =>
{
h.Username("guest");
h.Password("guest");
});
// sbc.ReceiveEndpoint(host, "TestQueue",
// ep =>
// {
// ep.Handler<ExClass>(context => { return Console.Out.WriteLineAsync(context.Message.Message); });
// });
});
bus.Start();
bus.Publish(new ExClass(){Message = "Hello RabbitMQ!"});
}
}
}
変更点としては、メッセージキューの受け取りを行っていた部分をコメントしたことと、メッセージをPublish(送信)する部分を追加したことです。
これによって、処理されることのないメッセージが1個だけ送信されてメッセージキュー上にとどまり続けることになります。
なので、これからこのメッセージを読み出しに行きます。
コードが変更できたら、まずはRabbitMQとManagementを立ち上げます。
サンプルのアプリケーションをビルド&Runします。
Management画面にログインします。
Queuesタブに移動し、TestQueueを選択します。
下のメニューから、Get messagesを開き、Get Message(s)のボタンを押します。
うまくいけば、下記のようなPayloadを含んだメッセージを取得できます。
一部分は環境によって変わるのでマスクしています。
{
"messageId": "000d0000-2700-0a00-2365-08d755bec029",
"conversationId": "000d0000-2700-0a00-dd56-08d755bec034",
"sourceAddress": "[メッセージの作成元のアドレスがここに表示されます]",
"destinationAddress": "[メッセージの送り先のアドレスがここに表示されます]",
"messageType": [
"urn:message:massTransitEx:ExClass",
"urn:message:MassTransit:IConsumer"
],
"message": {
"message": "Hello RabbitMQ!"
},
"sentTime": "[メッセージを送信した時刻がここに表示されます]",
"headers": {},
"host": {
"machineName": "[発信元のマシンの名前がここに表示されます]",
"processName": "dotnet",
"processId": 17608,
"assembly": "[このメッセージが送信された元のコンポーネントのアセンブリ名が表示されます]",
"assemblyVersion": "1.0.0.0",
"frameworkVersion": "4.0.30319.42000",
"massTransitVersion": "6.0.0.0",
"operatingSystemVersion": "[OSのバージョン名がここに入ります]"
}
}
このようにすれば、MessageQueueを通るメッセージを取得して中身を読み出すことができます。
実際には、メッセージをPublishする側だけを起動してメッセージを送信させ、それをこの方法で読み出すことでメッセージのフォーマットを知ることができ、それによってフォーマットに沿って別のメッセージを作成して送信することができるようになります。
また、余談ですが、ここで受信したメッセージと以前の記事で紹介した送信するメッセージの内容は違っています。
具体的には、送信用のメッセージは今回読み出したメッセージよりかなり内容が少ないです。
これは、メッセージとして送信される情報のうち、すべての情報が処理に必須なわけではないためです。
今回の場合だと、messageTypeとmessageの内容があれば正常に処理されました。
messageの型とその内容さえ情報として持っていればメッセージは正常に処理されるようです。
まとめ
この方法は同じチームの先輩から教えてもらったものなのですが、これを知ってからメッセージを受け取って動作するコンポーネントの動作のチェックが随分と楽になりました。コンポーネントを二つも走らせることによるコンピュータへの負荷が減り、開発がかなり捗るようになりました。
最近はイベント駆動やメッセージ駆動でアプリケーション間通信を実装することもあるため、この方法は知っておくと役に立つように思います。
お役に立てられれば幸いです。