具有以相同字符串开头的过滤器的 ZeroMQ (cppzmq) 订阅者
ZeroMQ (cppzmq) subscriber with filters which start with the same string
我在示例发布者中使用了两个主题。两者都以相同的字符串开头。当我仅使用两个主题之一过滤订阅者中的消息时,订阅者会收到两个主题
如果我使用两个不同的主题,它会起作用
我的示例发布商
try (ZContext context = new ZContext()) {
final ZMQ.Socket socket = context.createSocket(SocketType.PUB);
socket.bind("tcp://*:5555");
int i = 0;
while (!Thread.currentThread().isInterrupted() && !stopped) {
logger.debug("sending C1 message");
final String env = "topic";
final String msg = "Hello, world #" + i++;
socket.sendMore(env);
socket.send(msg);
logger.debug("sending C2 message");
final String env2 = "topic2";
final String msg2 = "Hello, world #" + i++;
socket.sendMore(env2);
socket.send(msg2);
try {
sleep(5000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我的示例订阅者:
zmq::context_t ctx;
zmq::socket_t sock(ctx, zmq::socket_type::sub);
sock.connect("tcp://127.0.0.1:5555");
std::string filter="topic";
sock.setsockopt(ZMQ_SUBSCRIBE,filter.c_str(),filter.length());
while(true) {
zmq::message_t env;
sock.recv(&env);
std::string env_str = std::string(static_cast<char*>(env.data()), env.size());
std::cout << "Received Enveloppe '" << env_str << "'" << std::endl;
zmq::message_t msg;
sock.recv(&msg);
std::string msg_str = std::string(static_cast<char*>(msg.data()), msg.size());
std::cout << "Received '" << msg_str << "'" << std::endl;
}
我的订阅者应该只显示与主题 "topic" 相关的消息,而不是两者。
Statement : "My subscriber should display only the message associated to the topic "topic" and not both."
不正确,恰恰相反。
这方面的文档很清楚。 ZeroMQ API 明确指出:
A non-empty option_value
shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.
+-----------------------+---------------+
| Option value type | binary data |
+-----------------------+---------------+
示例:
一条消息,在 PUB
端发送为:
PUB.send( "123456------------" );
将在以下任一项订阅中获得 .recv()
-ed SUB
-s:
SUB.setsockopt( zmq.SUBSCRIBE, "" ); // this one .recv()-es EVERY message
SUB.setsockopt( zmq.SUBSCRIBE, "1" ); // this one .recv()-es "1{0+[*]}"
SUB.setsockopt( zmq.SUBSCRIBE, "12" ); // this one .recv()-es "12{0+[*]}"
SUB.setsockopt( zmq.SUBSCRIBE, "123" );// this one .recv()-es "123{0+[*]}"
我在示例发布者中使用了两个主题。两者都以相同的字符串开头。当我仅使用两个主题之一过滤订阅者中的消息时,订阅者会收到两个主题
如果我使用两个不同的主题,它会起作用
我的示例发布商
try (ZContext context = new ZContext()) {
final ZMQ.Socket socket = context.createSocket(SocketType.PUB);
socket.bind("tcp://*:5555");
int i = 0;
while (!Thread.currentThread().isInterrupted() && !stopped) {
logger.debug("sending C1 message");
final String env = "topic";
final String msg = "Hello, world #" + i++;
socket.sendMore(env);
socket.send(msg);
logger.debug("sending C2 message");
final String env2 = "topic2";
final String msg2 = "Hello, world #" + i++;
socket.sendMore(env2);
socket.send(msg2);
try {
sleep(5000);
} catch (final InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我的示例订阅者:
zmq::context_t ctx;
zmq::socket_t sock(ctx, zmq::socket_type::sub);
sock.connect("tcp://127.0.0.1:5555");
std::string filter="topic";
sock.setsockopt(ZMQ_SUBSCRIBE,filter.c_str(),filter.length());
while(true) {
zmq::message_t env;
sock.recv(&env);
std::string env_str = std::string(static_cast<char*>(env.data()), env.size());
std::cout << "Received Enveloppe '" << env_str << "'" << std::endl;
zmq::message_t msg;
sock.recv(&msg);
std::string msg_str = std::string(static_cast<char*>(msg.data()), msg.size());
std::cout << "Received '" << msg_str << "'" << std::endl;
}
我的订阅者应该只显示与主题 "topic" 相关的消息,而不是两者。
Statement : "My subscriber should display only the message associated to the topic "topic" and not both."
不正确,恰恰相反。
这方面的文档很清楚。 ZeroMQ API 明确指出:
A non-empty
option_value
shall subscribe to all messages beginning with the specified prefix. Multiple filters may be attached to a single ZMQ_SUB socket, in which case a message shall be accepted if it matches at least one filter.
+-----------------------+---------------+
| Option value type | binary data |
+-----------------------+---------------+
示例:
一条消息,在 PUB
端发送为:
PUB.send( "123456------------" );
将在以下任一项订阅中获得 .recv()
-ed SUB
-s:
SUB.setsockopt( zmq.SUBSCRIBE, "" ); // this one .recv()-es EVERY message
SUB.setsockopt( zmq.SUBSCRIBE, "1" ); // this one .recv()-es "1{0+[*]}"
SUB.setsockopt( zmq.SUBSCRIBE, "12" ); // this one .recv()-es "12{0+[*]}"
SUB.setsockopt( zmq.SUBSCRIBE, "123" );// this one .recv()-es "123{0+[*]}"