Biribu
Biribu

Reputation: 3833

Auto-reconnect in zmq subscriber

I have a server which sometimes sends some messages to all subscribers. With somethimes I mean, maybe one per month. Maybe one day it needs to send 100 and after that, it spends some months without sending more. But I need it to be able to do it.

Until now I have a publisher in python which sends the frames and a subscriber, in python too, in each end device. The script in the end devices seems to disconnect after a while. In my tests, I can send messages for some time but if I leave to send them for about, lets say, 10 minutes, the next message is never received.

Is there a way to allow the subscriber to send a heartbeat or something like that from time to time? Or detect the disconnect and reconnect as soon as it can? I don't mind to miss a package because I have a message control so it will receive it within the next minute if no answer is received by the server.

I have this code to connect to the server:

portSubOuter = "6100"
context = zmq.Context()
socketOuter = context.socket(zmq.SUB)
socketOuter.connect("tcp://my_domain_url:%s"% portSubOuter)
socketOuter.setsockopt(zmq.SUBSCRIBE, '')

And this is my code to read:

macRecv = socketOuter.recv()
print "Packet for mac: %s"%macRecv
if macRecv == repr(myMACOuter):
    more = True
    while more:
        part_received = socketOuter.recv()
        part.append(part_received)
        more = socketOuter.getsockopt(zmq.RCVMORE)
    ....

Do I need to implement the heartbeats in the publisher side? Like send a message each 2 mins or so?

Upvotes: 4

Views: 3270

Answers (1)

dsolimano
dsolimano

Reputation: 9006

Heartbeats are a fine solution, but I think what you're looking for is the ZMQ Keepalive feature. See the zmq_setsockopt man page, particularly these options

ZMQ_TCP_KEEPALIVE
ZMQ_TCP_KEEPALIVE_IDLE
ZMQ_TCP_KEEPALIVE_CNT
ZMQ_TCP_KEEPALIVE_INTVL

In C#, I'm doing something like this as a default in my implementation, which ultimately maps down to the options above. Not sure what your binding looks like, but there are either similar properties or the zmq_setsockopt call. Mileage may vary depending on your OS and network

_socket.Options.TcpKeepalive = Enable
_socket.Options.TcpKeepaliveIdle = (int)new TimeSpan(0, 5, 0).TotalSeconds;
_socket.Options.TcpKeepaliveInterval = (int)new TimeSpan(0, 0, 30).TotalSeconds;

Upvotes: 3

Related Questions