1

I am fairly new to pyzmq. I am trying to understand inproc: transport class and have created this sample example to play with.

It looks a Publisher instance is publishing messages but Subscriber instances are not receiving any.

In case I move Subscriber instances into a separate process and change inproc: to a tcp: transport class, the example works.

Here is the code:

import threading
import time

import zmq

context = zmq.Context.instance()

address = 'inproc://test' 


class Publisher(threading.Thread):
    def __init__(self):
        self.socket = context.socket(zmq.PUB)

        self.socket.bind(address)

    def run(self):
        while True:
            message = 'snapshot,current_time_%s' % str(time.time())
            print 'sending message %s' % message
            self.socket.send(message)
            time.sleep(1)


class Subscriber(object):
    def __init__(self, sub_name):
        self.name = sub_name
        self.socket = context.socket(zmq.SUB)
        self.socket.connect(address)

    def listen(self):
        while True:
            try:
                msg = self.socket.recv()
                a, b = msg.split(' ', 1)
                print 'Received message -> %s-%s-%s' % (self.name, a, b)
            except zmq.ZMQError as e:
                logger.exception(e)


if __name__ == '__main__':
    thread_a = []
    for i in range(0, 1):
        subs = Subscriber('subscriber_%s' % str(i))
        th = threading.Thread(target=subs.listen)
        thread_a.append(th)
        th.start()

    pub = Publisher()
    pub_th = threading.Thread(target=pub.run)

    pub_th.start()
user3666197
  • 1
  • 6
  • 50
  • 92
sachin
  • 35
  • 1
  • 5
  • `except ... pass` ... seriously? BTW: Upgrade to Python 3! – Ulrich Eckhardt Dec 01 '15 at 05:31
  • ;-), that was just a sample code. Fixed it in the example :). – sachin Dec 02 '15 at 06:02
  • So I ran into this on ZMQ 4.3.2 in C++. And ensured that bind was called before connect. And my receive call never receives anything. One thing I noticed in the bind and connect code documentation it claims these are async functions, making this even more problematic since just ensuring bind is called before connect may not be enough depending on how things are implemented. So I even ensured the bind was completed but even with that my receive still never returned with any data. – David Bradley May 01 '22 at 15:32

1 Answers1

2

There is nothing wrong, but

ZeroMQ is a wonderfull toolbox.

It is full of smart, bright and self-adapting services under the hood, that literally save our poor lives in many ways.

Still it is worth to read and obey a few rules from the documentation.

inproc transport class has one such. .bind() first, before .connect()-s

[ Page 38, Code Connected, Volume I ]

... inproc is an inter-thread signalling transport ... it is faster than tcp or ipc. This transport has a specific limitation compared to tpc and icp: the server must issue a bind before any client issues a connect. This is something future versions of ØMQ may fix, but at present this defines how you use inproc sockets.

So, as an example:

if __name__ == '__main__':

    pub    = Publisher()
    pub_th = threading.Thread( target = pub.run )
    pub_th.start()
    # give it a place to start before .connect()-s may take place
    # give it a time  to start before .connect()-s may take place
    sleep(0.5)

    thread_a = []
    for i in range( 0, 1 ):
        subs = Subscriber( 'subscriber_%s' % str( i ) )
        th   = threading.Thread( target = subs.listen )
        thread_a.append( th )
        th.start()
user3666197
  • 1
  • 6
  • 50
  • 92