16

多くのパーツを含む小さなシステムを構築しており、メッセージpub/subサービスを使用してパーツ間で通信したいと考えています。

RabbitMQやZeroMQのようないくつかのメッセージキューサービスについて読みましたが、それらは複雑すぎて、分散システム用に生まれたように感じます。私のシステムのすべての部分はC++/ Linuxで書かれ、小さなRaspberry Pi CPUに配置されるので、スケーラブルなクロスプラットフォームのその他の言語クライアントのような機能は必要ありません...

私のニーズに合ったサービスやライブラリについてアドバイスをいただけますか?

4

3 に答える 3

8

実際に自分で行うのはそれほど難しいことではありません。

まず、使用するプロトコルを定義する必要があります。とても簡単です。メッセージ タイプ フィールド、ペイロード サイズ フィールド、実際のペイロードのように。必要なメッセージ タイプSUBSCRIBEUNSUBSCRIBEおよびPUBLISH. SUBSCRIBEおよびメッセージのペイロードは、UNSUBSCRIBEサブスクライブ/サブスクライブ解除するチャネルの名前です。メッセージのペイロードPUBLISHは、チャネル名と実際のデータです (もちろんデータのサイズも一緒です)。

すべての加入者を接続するには、中央サーバーが必要です。すべてのサブスクライバー/パブリッシャーは、このサーバーに接続する必要があります。サーバー プログラムは、チャネルごとに 1 つのキューのコレクションを保持します。存在しないチャネルのサブスクライブまたはパブリッシュ メッセージがサーバーに到着した場合は、このチャネルの新しいメッセージ キューを作成します。サーバーは、チャネルごとに、そのチャネルにサブスクライブしているすべてのクライアントのコレクションも必要とします。パブリッシュ メッセージがサーバーに到着すると、問題のチャネルのキューの最後に追加されます。チャネル キューが空でない間は、そのコピーをそのチャネルのすべてのサブスクライバーに送信し、すべてがそれを受信したら、メッセージをキューから削除できます。

サーバーの難しい部分は、おそらく通信部分になるでしょう。簡単な部分は、すべてのキューとコレクションになります。これは、C++ 標準コンテナーをすべて (std::queue実際のキュー、std::unordered_mapチャネル、およびstd::vector接続されたクライアントのコレクションなど) に使用できるためです。

クライアントは非常に単純です。必要なのは、サブスクリプションとパブリッシュ メッセージをサーバーに送信し、サーバーからパブリッシュ メッセージを受信できることだけです。難しい部分は、実際のコミュニケーション部分です。


追記:

私は実際にそのようなシステムを自分で構築したことはありません.上記のすべては、私の頭のてっぺんに直接ありました. 経験豊富なプログラマーは、基本を実装するのに数時間以上かかることはありません。経験の浅いプログラマーの場合は、おそらく数日かかります。

Boost ASIOなどを使用できる通信には、チャネルごとに 1 つのスレッドを使用できます。また、 Boost プロパティ ツリーのようなものを使用して、JSONまたはXMLメッセージを構築/解析できます。

ただし、これはすべて車輪の再発明のようなもので、RabbitMQ のような既存のシステムの 1 つを数時間で使い始めることができ、多くの時間を節約できます (そして多くのバグも!)

于 2013-01-22T09:22:23.853 に答える
7

軽量サーバーに関する限り、Redisは pub/sub コマンドをサポートしています。

Redis コード自体は非常にタイトで (2 つのファイルのみ)、シングル スレッド (イベント ループを使用) であり、メモリ消費量は非常に低くなっています (私が見た他の Queing システムと比較して)。

于 2013-01-22T09:38:59.813 に答える
3

遅いことはわかっていますが、他の人にとっては役立つかもしれません。ブーストを使用して C++ で基本的な pub/sub を実装しました。

CppPubSub

使い方はとても簡単です。一方の端からチャンネルでデータ (ジェネリック マップ) を公開し、もう一方の側で同じチャンネルをサブスクライブして、ジェネリック マップを再度受け取ります。

// you should create a singleton object of NotificationService class, make it accessible throughout your application. 
INotificationService* pNotificationService = new NotificationService();

// Subscribe for the event.
function<NotificationHandler> fnNotificationHandler = bind(&SubscriberClass::NotificationHandlerFunction, this, std::placeholders::_1);
subscriptionToken = pNotificationService->Subscribe("TEST_CHANEL", fnNotificationHandler);

// Publish event
NotificationData _data;
_data["data1"] = "Hello";
_data["data2"] = "World";
pNotificationService->Publish("TEST_CHANEL", _data);

// Unsubscribe event.
pNotificationService->Unsubscribe(subscriptionToken);
于 2015-11-19T15:49:04.957 に答える