11

複数のパブリッシャーと複数のサブスクライバーが同じバス上に存在する pub/sub アーキテクチャを実行しようとしています。私がインターネットで読んだことによると、1 つのソケットだけが bind() を呼び出す必要があり、他のすべて (pub または sub) は connect() を呼び出す必要があります。

問題は、このアプローチでは、実際にソケットで bind() を呼び出すパブリッシャーのみがメッセージをパブリッシュすることです。connect() を呼び出すパブリッシャーはすべてサイレントに失敗したようで、実際にはバスにメッセージをパブリッシュしていません。これはサブスクライバー キーの問題ではないことを確認しました。バス上のすべてのメッセージをサブスクライブする単純な「スニファー」アプリを作成したところ、bind() を呼び出したパブリッシャーのみが表示されているからです。

パブリッシャーで複数のバインドを試みると、ipc でバスを黙って盗むという「予想される」zmq の動作が発生し、tcp で port in use エラーがスローされます。

ipc および tcp エンドポイントでこの動作を確認しましたが、最終的にはシステム全体で epgm が使用されます。(もちろん間違っているかもしれませんが) この状況では、動的な検出が行われないため、ブローカーは必要ないと思います (ipc、tcp、epgm マルチキャストのいずれのエンドポイントも既知です)。

接続しているパブリッシャーが実際にデータを送信しない原因となるソケット設定など、私が見逃しているものはありますか? インターネットで見た文献によると、私は「正しい」方法で物事を行っていますが、それでも機能しません。

参考までに、私のパブリッシャー クラスには、エンドポイントを設定するための次のメソッドがあります。

ZmqPublisher::ZmqPublisher()
: m_zmqContext(1), m_zmqSocket(m_zmqContext, ZMQ_PUB)
{}


void ZmqPublisher::bindEndpoint(std::string ep)
{
    m_zmqSocket.bind(ep.c_str());
}

void ZmqPublisher::connect(std::string ep)
{
    m_zmqSocket.connect(ep.c_str());
}

最終的に、私の質問は次のとおりです: 同じエンドポイントで複数のパブリッシャーを処理する適切な方法は何ですか? 複数のパブリッシャーからのメッセージが表示されないのはなぜですか?

4

2 に答える 2

4

関連性があるかもしれないし、ないかもしれませんが、0MQ ガイドには、次の少し謎めいた発言があります。

ØMQ ソケットの理論では、どちらの端が接続され、どちらの端がバインドされるかは問題ではありません。ただし、実際には文書化されていない違いがありますが、これについては後で説明します。ここでは、ネットワーク設計でそれが不可能でない限り、PUB をバインドして SUB を接続します。

「後で来る」が実際にどこで発生するかはまだわかっていませんが、pub/subあまり使用しておらず、ガイドの「高度な Pub-Sub パターン」の部分を詳しく読んでいません。

ただし、単一のエンドポイントに複数のパブリッシャーを配置するという考えは、XPUB/XSUBスタイル ブローカーの必要性を示唆しています。これは動的な発見ではなく、単一の連絡先とルーティングに関するものです。最終的には、ブローカーベースのトポロジーがアプリケーションを簡素化し、問題の特定を容易にすると思います。

于 2013-08-27T13:05:59.513 に答える