So konfigurieren Sie ein Multiple PUB / Single SUB Python ZMQ Ubuntu

Nov 19 2020

Ich habe zwei VMs (VirtualBOx, Ubuntu 18.04 und python-zmq [16.0.2-2build2]), die auf derselben physischen Maschine (Win10) ausgeführt werden. Beide Computer sind als Bridge konfiguriert und können erfolgreich pingen. 192.168.1.66-192.168.1.55. Ich habe dieses Tutorial befolgthttps://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pubsub.html. Es funktioniert, wenn PUB (Server) als konfiguriert ist

import zmq
import random
import sys
import time

port = "5557"
if len(sys.argv) > 1:
    port =  sys.argv[1]
    int(port)

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)
while True:
    topic = random.randrange(9999,10005)
    messagedata = random.randrange(1,215) - 80
    print "%d %d" % (topic, messagedata)
    socket.send("%d %d" % (topic, messagedata))
    time.sleep(1)

Und der SUB (Kunde) als

import sys
import zmq

port = "5557"
if len(sys.argv) > 1:
    port =  sys.argv[1]
    int(port)
    
if len(sys.argv) > 2:
    port1 =  sys.argv[2]
    int(port1)

# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)

print "Collecting updates from weather server..."
socket.connect ("tcp://192.168.1.66:%s" % port)

if len(sys.argv) > 2:
    socket.connect ("tcp://localhost:%s" % port1)
# Subscribe to zipcode, default is NYC, 10001
topicfilter = "10001"
socket.setsockopt(zmq.SUBSCRIBE, topicfilter)

# Process 5 updates
total_value = 0
for update_nbr in range (5):
    string = socket.recv()
    topic, messagedata = string.split()
    total_value += int(messagedata)
    print topic, messagedata

print "Average messagedata value for topic '%s' was %dF" % (topicfilter, total_value / update_nbr)

Da ich einen einzelnen Client (SUB) mit mehreren Servern (PUB) möchte, bei denen es sich um Hunderte oder sogar Tausende handeln kann, ist es nicht möglich, für jeden PUB eine einzelne IP zu konfigurieren. Gibt es eine Möglichkeit zum Abonnieren ohne Angabe der IP? Oder zumindest eine Sendung. Ich habe versucht, auf dem Client zu konfigurieren in socket.connect ("tcp://IP:%s" % port):

"*"

Gibt den Fehler:

Traceback (most recent call last):
  File "sub_client.py", line 18, in <module>
    socket.connect ("tcp://*:%s" % port)
  File "zmq/backend/cython/socket.pyx", line 528, in zmq.backend.cython.socket.Socket.connect (zmq/backend/cython/socket.c:5980)
  File "zmq/backend/cython/checkrc.pxd", line 25, in zmq.backend.cython.checkrc._check_rc (zmq/backend/cython/socket.c:8400)
zmq.error.ZMQError: Invalid argument

192.168.1.1 (GW), 192.168.1.255 (Broadcast), localhost / 127.0.0.1 und seine IP (192.168.1.55) -> empfangen keine Nachrichten

192.168.1.66 (IP des Servers) -> Empfängt Nachrichten, ist jedoch in einem großen System nicht praktikabel

Wie kann man das lösen?

Antworten

user3666197 Nov 19 2020 at 22:21

F : Gibt es eine Möglichkeit, dies zu lösen?

Vermeiden Sie es, gegen API-dokumentierte Eigenschaften vorzugehen. Während eine -method .bind()für die tcp://-transport-Klasse versuchen kann, tatsächlich an beliebige localhost-side-IP-Adressen zu binden, kann die -method .connect()aus offensichtlichen Gründen nicht.

Wie in der ZMQError:

socket.connect ("tcp://*:%s" % port)
zmq.error.ZMQError: Ungültiges Argument

Korrigieren Sie das IP-Adressziel, wo die
.connect( "tcp://{0:}:{1:}".format( IP, PORT ) )Methode versuchen soll, "so zu klingeln, um eine Verbindung herzustellen".