ZeroMQ:如何将轮询器中使用的 pollitem_t 项转换回 ZeroMQ 套接字?
ZeroMQ: How to cast a pollitem_t item, used in Poller, back to a ZeroMQ socket?
正如标题所说,当 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;
}
因此问题:
在这种情况下是否无法避免对套接字进行硬编码?
Q : Is it impossible to avoid hardcoding sockets in this case?
是的。
这是为什么部分 :
1 )
API 记录的 Poller
-setup 要求我们填写-在 pollitem_t item
(s) 中进入强制数据结构,Poller
-实例期望从我们这里接收。 (所以这部分是必备的,而且没有想象中的
"avoidance"-这里可能有技巧 - 不透明 void*
必须交付给Poller
以便按预期工作......确实 .poll()
某事...... )
2 )
A "reverse" 转码(硬编码与否) 没有必要(因此这里没有什么可以避免的),因为第 1 步 - 您的代码已经知道 "map" - 它已经生成了 1:1-map-of -pollitem_t item
(s) 用于强制交付给 Poller
接受审查。
结语:
对于数量的Socket
实例,这恰好是强制性(即无法避免) 1:1-map-of-pollitem_t item
s 数据结构(您开始将其称为 "hardcoding" 部分),可以为静态案例设计脚本工具(对于已知 Socket
-要处理的实例)或自适应地图生成器,它将使用您自己的托管试验-"tape"(您系统维护的数据结构),所有 Socket
-要处理的实例)。
从 zmq.hpp header:
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
及其包。
正如标题所说,当 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;
}
因此问题:
在这种情况下是否无法避免对套接字进行硬编码?
Q : Is it impossible to avoid hardcoding sockets in this case?
是的。
这是为什么部分 :
1 )
API 记录的 Poller
-setup 要求我们填写-在 pollitem_t item
(s) 中进入强制数据结构,Poller
-实例期望从我们这里接收。 (所以这部分是必备的,而且没有想象中的
"avoidance"-这里可能有技巧 - 不透明 void*
必须交付给Poller
以便按预期工作......确实 .poll()
某事...... )
2 )
A "reverse" 转码(硬编码与否) 没有必要(因此这里没有什么可以避免的),因为第 1 步 - 您的代码已经知道 "map" - 它已经生成了 1:1-map-of -pollitem_t item
(s) 用于强制交付给 Poller
接受审查。
结语:
对于数量的Socket
实例,这恰好是强制性(即无法避免) 1:1-map-of-pollitem_t item
s 数据结构(您开始将其称为 "hardcoding" 部分),可以为静态案例设计脚本工具(对于已知 Socket
-要处理的实例)或自适应地图生成器,它将使用您自己的托管试验-"tape"(您系统维护的数据结构),所有 Socket
-要处理的实例)。
从 zmq.hpp header:
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
及其包。