I don't know that this is any less complicated (and it's C++, not C), but azmq integrates libzmq FD handling with Boost Asio's event loop, and that can be 'manually' pumped by calling io_service::poll_one() from inside another event dispatch loop.
https://github.com/zeromq/azmq On Thu, Jul 27, 2017 at 9:37 AM Luca Boccassi <[email protected]> wrote: > glib is ridiculously complicated. > > When we had to use it what we did was creating a GIOChannel from the > file descriptor (again this is from ZMQ_FD, not just the socket) with > g_io_channel_unix_new, then creating a GSource from that with > g_io_create_watch, then attaching the callback to the source with > g_source_set_callback, and then finally attaching the source to the > g_task with g_task_attach_source. > > This worked fine and we shipped a few releases using it. > > On Thu, 2017-07-27 at 17:03 +0300, Alexander Yanin wrote: > > Hi, > > > > Thank you for the provided article. This article covers the main > > approach > > to integrating zmq fd into event loops more precisely than > > stackoverflow > > threads I've linked to my question. But it seems that there is still > > no > > answer to my question there, because my problem is in the very > > beginning of > > an integration process - I never get my IO_IN callback triggered :) > > In other words, when I call `recv` method in a for loop directly, I > > got > > data, but when I connect zmq file descriptor to glib event loop to > > listen > > to IO_IN conditions, lambda function that handles such events is > > never > > called. > > I've also tried connecting to other conditions than IO_IN, actually > > to all > > others (IO_ERR, IO_PRI, etc), but the result was the same except with > > IO_OUT. IO_OUT condition triggers the callback, but writing to fd is > > not my > > case, as I am using ZMQ_SUB socket which is only for read purpose. > > > > 2017-07-27 15:55 GMT+03:00 Luca Boccassi <[email protected]>: > > > > > On Thu, 2017-07-27 at 15:02 +0300, Alexander Yanin wrote: > > > > I am trying to integrate ZeroMQ into my Glib main event loop. As > > > > I > > > > have > > > > seen on the official ZeroMQ FAQ and API reference and on some > > > > stackoverflow > > > > threads (zeromq glib main loop integration > > > > <https://stackoverflow.com/questions/6695863/zeromq-glib-main-loo > > > > p-in > > > > tegration> > > > > and How to use ZeroMQ in an GTK/QT/Clutter application? > > > > <https://stackoverflow.com/questions/6452131/how-to-use-zeromq-in > > > > -an- > > > > gtk-qt-clutter-application>), > > > > to do this I need to get ZeroMQ FD and then connect it to > > > > existing > > > > event > > > > loop. But, unfortunately, In my case this does not work. > > > > > > > > here is the code: > > > > > > > > RefPtr<IOChannel> zmq_in; > > > > zmq::context_t context (1); > > > > zmq::socket_t subscriber (context, ZMQ_SUB); > > > > > > > > subscriber.connect("tcp://localhost:5556");const char *filter = > > > > "10001 "; > > > > subscriber.setsockopt(ZMQ_SUBSCRIBE, filter, strlen (filter)); > > > > const auto read_zmq = [this, &subscriber](Glib::IOCondition c) -> > > > > bool { > > > > std::cout << " Received message on zmq!" << std::endl; > > > > int zipcode, temperature, relhumidity; > > > > zmq::message_t update; > > > > subscriber.recv(&update); > > > > std::istringstream iss(static_cast<char*>(update.data())); > > > > iss >> zipcode >> temperature >> relhumidity; > > > > std::cout << "Zipcode: " << zipcode << " Temperature: " << > > > > temperature > > > > << "Humidity: " << relhumidity; > > > > return true;}; > > > > for (int i = 0; i < 10 ; i++) { > > > > int zipcode, temperature, relhumidity; > > > > zmq::message_t update; > > > > subscriber.recv(&update); > > > > std::istringstream iss(static_cast<char*>(update.data())); > > > > iss >> zipcode >> temperature >> relhumidity; > > > > std::cout << "Zipcode: " << zipcode << " Temperature: " << > > > > temperature > > > > << " Humidity: " << relhumidity << std::endl;} > > > > int fd = subscriber.getsockopt<int>(ZMQ_FD); > > > > zmq_in = IOChannel::create_from_fd(fd); > > > > Glib::signal_io().connect(read_zmq, zmq_in, Glib::IO_IN); > > > > > > > > What really happens when the code is executed: 10 messages are > > > > successfully > > > > received from Publisher (another process) in the for loop, but > > > > when > > > > it > > > > comes to receiving messages from the Glib main event loop, my c++ > > > > lambda is > > > > never called :( > > > > > > > > Here is the Publisher code in C almost completely taken from > > > > ZeroMQ > > > > Guide: > > > > > > > > #include <zmq.h>#include <stdio.h>#include <unistd.h>#include > > > > <string.h>#include <assert.h>#include <stdlib.h> > > > > int main (void){ > > > > // Prepare our context and publisher > > > > void *context = zmq_ctx_new (); > > > > void *publisher = zmq_socket (context, ZMQ_PUB); > > > > int rc = zmq_bind (publisher, "tcp://*:5556"); > > > > assert (rc == 0); > > > > > > > > // Initialize random number generator > > > > while (1) { > > > > // Get values that will fool the boss > > > > int zipcode, temperature, relhumidity; > > > > zipcode = rand () % 100000; > > > > temperature = (rand () % 215) - 80; > > > > relhumidity = (rand () % 50) + 10; > > > > > > > > // Send message to all subscribers > > > > char update [20]; > > > > sprintf (update, "%05d %d %d", zipcode, > > > > temperature, > > > > relhumidity); > > > > zmq_send (publisher, update, 20, 0); > > > > int ev; > > > > size_t sizeof_ev = sizeof(ev); > > > > } > > > > zmq_close (publisher); > > > > zmq_ctx_destroy (context); > > > > return 0;} > > > > > > > > So where is the problem? > > > > > > > > P.S.:I am using glibmm c++ binding to Glib. My OS is Fedora 26. > > > > My > > > > ZeroMQ > > > > version is 4.1.6 > > > > > > Hi, > > > > > > I have no idea about that specific c++ glib binding, but as the > > > answer > > > on the first link you posted says you can't just poll a ZMQ socket, > > > you > > > need to get the file descriptor via the ZMQ_FD socket option and > > > feed > > > that to the poll, and then read in a loop as long as the ZMQ_EVENTS > > > socket options returns ZMQ_POLLIN. > > > > > > This is because those FDs are edge triggered: > > > > > > https://funcptr.net/2012/09/10/zeromq---edge-triggered-notification > > > / > > > > > > -- > > > Kind regards, > > > Luca Boccassi > > > _______________________________________________ > > > zeromq-dev mailing list > > > [email protected] > > > https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > > > > > > _______________________________________________ > > zeromq-dev mailing list > > [email protected] > > https://lists.zeromq.org/mailman/listinfo/zeromq-dev > > -- > Kind regards, > Luca Boccassi_______________________________________________ > zeromq-dev mailing list > [email protected] > https://lists.zeromq.org/mailman/listinfo/zeromq-dev
_______________________________________________ zeromq-dev mailing list [email protected] https://lists.zeromq.org/mailman/listinfo/zeromq-dev
