Cara mengkonfigurasi Multiple PUB / single SUB python ZMQ Ubuntu

Nov 19 2020

Saya memiliki dua VM (VirtualBOx, Ubuntu 18.04 dan python-zmq [16.0.2-2build2]) yang berjalan dalam mesin fisik yang sama (Win10). Kedua mesin dikonfigurasi sebagai Bridge dan mereka dapat melakukan ping dengan sukses ke 192.168.1.66-192.168.1.55. Saya telah mengikuti tutorial inihttps://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pubsub.html. Ini berfungsi jika PUB (server) dikonfigurasi sebagai

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)

Dan SUB (klien) sebagai

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)

Karena saya menginginkan satu klien (SUB) dengan banyak server (PUB) di mana mereka bisa ratusan bahkan ribuan, tidak mungkin untuk mengonfigurasi satu IP untuk setiap PUB. Apakah ada cara untuk berlangganan tanpa menentukan IP? Atau setidaknya satu siaran. Saya sudah mencoba mengkonfigurasi di klien di socket.connect ("tcp://IP:%s" % port):

"*"

Memberikan kesalahan:

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 dan IP-nya (192.168.1.55) -> tidak menerima pesan

192.168.1.66 (server IP) -> Apakah menerima pesan tetapi tidak praktis dalam sistem skala besar

Ada cara untuk mengatasi ini?

Jawaban

user3666197 Nov 19 2020 at 22:21

T : Adakah cara untuk mengatasi ini?

Hindari melawan properti yang didokumentasikan API. Sementara .bind()-method bisa untuk kelas tcp://-transport mencoba untuk memang mengikat ke localhostalamat-IP sisi mana pun , .connect()-method, untuk alasan yang jelas tidak bisa.

Seperti yang diberitahukan di ZMQError:

socket.connect ("tcp://*:%s" % port)
zmq.error.ZMQError: Argumen tidak valid

Perbaiki target alamat IP, di mana metode-akan
.connect( "tcp://{0:}:{1:}".format( IP, PORT ) )mencoba untuk "menelepon-jadi-untuk-mendapatkan-koneksi".