ZeroMQ: Как привести предмет pollitem_t, используемый в Poller, обратно в сокет ZeroMQ? - PullRequest
1 голос
/ 31 октября 2019

Как видно из заголовка, при использовании zmq::poll с cppzmq я бы хотел избежать жесткого кодирования перевода сокетов ZeroMQ в pollitem_t item (s) для опроса.

Но, похоже, мне не разрешено преобразовывать void* pollitem_t::socket обратно в сокет zmq.

Я заметил, что официальный пример кода просто закодировал сокет после опроса.

//
//  Reading from multiple sockets in C++
//  This version uses zmq_poll()
//
// Olivier Chamoux <olivier.chamoux@fr.thalesgroup.com>

#include "zhelpers.hpp"

int main (int argc, char *argv[])
{
    zmq::context_t context(1);

    //  Connect to task ventilator
    zmq::socket_t receiver(context, ZMQ_PULL);
    receiver.connect("tcp://localhost:5557");

    //  Connect to weather server
    zmq::socket_t subscriber(context, ZMQ_SUB);
    subscriber.connect("tcp://localhost:5556");
    subscriber.setsockopt(ZMQ_SUBSCRIBE, "10001 ", 6);

    //  Initialize poll set
    zmq::pollitem_t items [] = {
        { static_cast<void*>(receiver), 0, ZMQ_POLLIN, 0 },
        { static_cast<void*>(subscriber), 0, ZMQ_POLLIN, 0 }
    };
    //  Process messages from both sockets
    while (1) {
        zmq::message_t message;
        zmq::poll (&items [0], 2, -1);

        if (items [0].revents & ZMQ_POLLIN) {
            receiver.recv(&message);
            //  Process task
        }
        if (items [1].revents & ZMQ_POLLIN) {
            subscriber.recv(&message);
            //  Process weather update
        }
    }
    return 0;
}

Отсюда вопрос:

Нельзя ли в этом случае избежать жесткого кодирования сокетов?

Ответы [ 2 ]

1 голос
/ 31 октября 2019

Обдумал это вместе из заголовка zmq.hpp:

zmq::poller_t poller;
poller.add({from_handle, receiver.handle()}, event_flags::pollin});
poller.add({from_handle, subscriber.handle()}, event_flags::pollin});

// This vector must be at least as large as the number of sockets being polled
vector<zmq::poller_event> events(2);
while (true) {
  size_t num_events = poller.wait_all(events, -1);
  // You may need to sleep a bit if num_events == 0

  for (int i = 0; i < num_events; i++) {
    zmq::message message;
    events[i].socket.recv(&message);
    ...
  } 
}

РЕДАКТИРОВАТЬ: понял, что структура poller_event также содержит socket_ref! Это делает все еще проще!

В стабильном выпуске zmq вам нужно #define ZMQ_BUILD_DRAFT_API, чтобы использовать poller_t и его сумку.

1 голос
/ 31 октября 2019

Q : Разве невозможно избежать жесткого кодирования сокетов в этом случае?

Да.

Это часть ПОЧЕМУ :

1)
Для задокументированного API Poller -установка требует от насвведите pollitem_t item (s) в обязательную структуру данных, которую Poller -экземпляр ожидает получить от нас. (Таким образом, эта часть ОБЯЗАТЕЛЬНА, и здесь здесь невозможно вообразить трюк "избегания" - непрозрачный void* ДОЛЖЕН быть доставлен на Poller, чтобы работать как положено ... на самом деле .poll() что-то ...)

2)
"обратное" транскодирование (жестко или нет) не нужно (таким образом, здесь нечего избегать) , верно из-за шага 1 - ваш код уже знает «карту» - он сгенерировалкарта 1: 1 pollitem_t item для обязательной доставки к рассматриваемому Poller.


ЭПИЛОГ:

Для случаев, когда сумма Socket -экземпляров, которые являются предметом первоначального построения обязательного (т. Е. Невозможно избежать) 1: 1-map-of- pollitem_t item s структура данных (которую вы начали называть «жестко кодирующей» частью), можно разработать инструмент-скрипт для статических случаев (для случая известных Socket -объектов, которые будут обрабатываться)или адаптивная карта-генератор, который будет использовать ваш собственный управляемый пилот-файл - "ленту" (вашу систематически поддерживаемую структуру данных) со всеми Socket -обработанными экземплярами).

...