ZeroMQ (cppzmq) подписчик с фильтрами, которые начинаются с той же строки - PullRequest
0 голосов
/ 15 октября 2019

Я использую две темы в моем образце издателя. Оба начинаются с одной и той же строки. Когда я фильтрую сообщение в подписчике, используя только одну из двух тем, подписчик получает обе темы

Если я использую две разные темы, это работает

Мой пример издателя

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;
}

Мой подписчик должен отображать только сообщение, связанное с темой "theme", а не оба.

1 Ответ

0 голосов
/ 15 октября 2019

Заявление: "Мой подписчик должен отображать только сообщение, связанное с темой" theme ", а не оба."

Notверно, с точностью до наоборот.

Документация в этом понятна. ZeroMQ API прямо заявляет:

Непустое option_value должно подписаться на все сообщения начиная с с указанным префиксом. Несколько фильтров могут быть подключены к одному сокету ZMQ_SUB, и в этом случае сообщение должно быть принято, если оно соответствует хотя бы одному фильтру.

+ ----------------------- + --------------- +
|Тип значения параметра |двоичные данные |
+ ----------------------- + --------------- +

Пример: сообщение, отправленное на стороне 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+[*]}"
...