Cách cấu hình Ubuntu ZMQ Multiple PUB / single SUB python

Nov 19 2020

Tôi có hai máy ảo (VirtualBOx, Ubuntu 18.04 và python-zmq [16.0.2-2build2]) đang chạy trong cùng một máy vật lý (Win10). Cả hai máy đều được định cấu hình là Bridge và chúng có thể ping thành công 192.168.1.66-192.168.1.55. Tôi đã làm theo hướng dẫn nàyhttps://learning-0mq-with-pyzmq.readthedocs.io/en/latest/pyzmq/patterns/pubsub.html. Nó hoạt động nếu PUB (máy chủ) được định cấu hình là

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)

Và SUB (khách hàng) là

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)

Vì tôi muốn có một máy khách (SUB) với nhiều máy chủ (PUB) trong đó chúng có thể lên đến hàng trăm thậm chí hàng nghìn, nên không khả thi khi định cấu hình một IP cho mỗi PUB. Có cách nào để đăng ký mà không chỉ định IP không? Hoặc ít nhất là một chương trình phát sóng. Tôi đã cố gắng định cấu hình tại ứng dụng khách trong socket.connect ("tcp://IP:%s" % port):

"*"

Đưa ra lỗi:

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 và đó là IP (192.168.1.55) -> không nhận được tin nhắn

192.168.1.66 (IP của máy chủ) -> Có nhận được tin nhắn nhưng không thực tế trong một hệ thống quy mô lớn

Bất kỳ cách nào để giải quyết điều này?

Trả lời

user3666197 Nov 19 2020 at 22:21

Q : Bất kỳ cách nào để giải quyết điều này?

Tránh đi ngược lại bất kỳ thuộc tính nào được lập thành tài liệu API Trong khi .bind()-method có thể cho tcp://-transport-class cố gắng thực sự liên kết với bất kỳ localhostđịa chỉ IP bên nào, thì .connect()-method, vì những lý do rõ ràng là không thể.

Như đã được thông báo trong ZMQError:

socket.connect ("tcp://*:%s" % port)
zmq.error.ZMQError: Đối số không hợp lệ

Sửa lại đích địa chỉ IP, nơi
.connect( "tcp://{0:}:{1:}".format( IP, PORT ) )-method sẽ cố gắng "đổ chuông để nhận kết nối".