如何创建允许多个发布商和多个订阅者访问这些发布商的网络?
或者是否绝对需要使用消息代理?
import time
import zmq
from multiprocessing import Process
def bind_pub(sleep_seconds, max_messages, pub_id):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")
message = 0
while True:
socket.send_string("1 sending_func=bind_pub message_number=%s pub_id=%s" % (message, pub_id))
message += 1
if message >= max_messages:
break
time.sleep(sleep_seconds)
def bind_sub(sleep_seconds, max_messages, sub_id):
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.bind("tcp://*:5556")
socket.setsockopt_string(zmq.SUBSCRIBE, '1')
message_n = 0
while True:
message = socket.recv_string()
print(message + " receiving_func=bind_sub sub_id=%s" % sub_id)
message_n += 1
if message_n >= max_messages - 1:
break
time.sleep(sleep_seconds)
def conect_pub(sleep_seconds, max_messages, pub_id):
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://localhost:5556")
message = 0
while True:
socket.send_string("1 sending_func=conect_pub message_number=%s pub_id=%s" % (message, pub_id))
message += 1
if message >= max_messages:
break
time.sleep(sleep_seconds)
def connect_sub(sleep_seconds, max_messages, sub_id):
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
socket.setsockopt_string(zmq.SUBSCRIBE, '1')
message_n = 0
while True:
message = socket.recv_string()
print(message + " receiving_func=connect_sub sub_id=%s" % sub_id)
message_n += 1
if message_n >= max_messages - 1:
break
time.sleep(sleep_seconds)
尝试bind_pub时,connect_pub,connect_sub,connect_sub网络架构:
# bind_pub, connect_pub, connect_sub, connect_sub
n_messages = 4
p1 = Process(target=bind_pub, args=(1,n_messages,1))
p2 = Process(target=conect_pub, args=(1,n_messages,2))
p3 = Process(target=connect_sub, args=(0.1,n_messages,1))
p4 = Process(target=connect_sub, args=(0.1,n_messages,2))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
pub_id=2
消息丢失的结果:
1 sending_func=bind_pub message_number=1 pub_id=1 receiving_func=connect_sub sub_id=2
1 sending_func=bind_pub message_number=1 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=2 pub_id=1 receiving_func=connect_sub sub_id=2
1 sending_func=bind_pub message_number=2 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=3 pub_id=1 receiving_func=connect_sub sub_id=1
1 sending_func=bind_pub message_number=3 pub_id=1 receiving_func=connect_sub sub_id=2
同样运行connect_pub,connect_pub,connect_sub,bind_sub架构:
# connect_pub, connect_pub, connect_sub, bind_sub
n_messages = 4
p1 = Process(target=conect_pub, args=(1,n_messages,1))
p2 = Process(target=conect_pub, args=(1,n_messages,2))
p3 = Process(target=bind_sub, args=(0.1,n_messages,1))
p4 = Process(target=connect_sub, args=(0.1,n_messages,2))
p1.start()
p2.start()
p3.start()
p4.start()
p1.join()
p2.join()
p3.join()
p4.join()
sub_id=2
未收到任何消息的结果:
1 sending_func=conect_pub message_number=1 pub_id=1 receiving_func=bind_sub sub_id=1
1 sending_func=conect_pub message_number=1 pub_id=2 receiving_func=bind_sub sub_id=1
1 sending_func=conect_pub message_number=2 pub_id=1 receiving_func=bind_sub sub_id=1
答案 0 :(得分:2)
这意味着第二个问题先验地解决了 - 不,它不仅不 绝对必要,它也主要是不可能的(如果没有实现< em> Broker - (半)持久性作为Zen-of-Zero标准的ZeroMQ工具,可以添加额外的附加组件。
这是一个经常被重新表达的错误观念,所以让我以粗体重复。
<强>请注意:强>
ZeroMQ $pid = getmypid();
$cpu = exec("ps hup $pid|awk '{print $3}'");
-instance不是tcp-socket-as-you-know-it。最好阅读 ZeroMQ hierarchy in less than a five seconds 或其他帖子和讨论中的主要概念差异。
ZeroMQ可以全部服务:
Socket()
其中全部或部分“很多”仍可以 many-PUB-s : many-SUB-s -or-
one-PUB : many-SUB-s -or- even
many-PUB-s : one-SUB
-ed到一个或多个AccessPoints,因此生成的拓扑结构可能确实存在狂野(详情请查看以上提供的link to a "five seconds" read)因此,一个人自己的想象力似乎是这样做的唯一上限。
对于性能和延迟信封,请随意seek and read more in other posts.
答案 1 :(得分:1)
当然没有必要使用代理来实现多对多网络,但代理确实简化了配置,因为每个节点只需要知道代理的地址,而不是所有的对等节点。
另一种可能性是混合方法——使用代理在对等点之间交换地址信息,以便它们可以直接相互连接。您可以在此处找到示例:https://github.com/nyfix/OZ/blob/master/doc/Naming-Service.md