将 ZMQ PUB 与 .connect() 或 .bind() 方法一起使用有什么区别?
What is the difference between using ZMQ PUB with .connect() or .bind() methods?
在PythonZMQpublisher/subscriber示例模板中,发布者使用.bind()
方法和订户使用 .connect()
连接到绑定 IP 地址的方法。
但是我们可以将.bind()
和.connect()
互相替换。
我的问题是下面确定的两种情况有什么区别?
(在这些情况下,两个脚本都可以正常工作)
第一种情况,默认为:
pub1.py:
import zmq
import time
from datetime import datetime
def create_pub_socket():
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://127.0.0.1:9002") # notice
return socket
def publish(pub_socket):
message = {
'data': 'hi my name is benyamin',
'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
}
pub_socket.send_json(message, 0)
return message
if __name__ == '__main__':
socket = create_pub_socket()
while True:
print('\n')
print('publisher: ', publish(socket))
time.sleep(1)
sub1.py:
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
socket.connect("tcp://127.0.0.1:9002") # notice
while True:
data = socket.recv_json()
print('subscriber: ', data)
print('\n')
第二种情况,作为修改后的设置,颠倒了 .connect()
和 .bind()
方法的使用:
pub2.py:
import zmq
import time
from datetime import datetime
def create_pub_socket():
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://127.0.0.1:9002") # notice
return socket
def publish(pub_socket):
message = {
'data': 'hi my name is benyamin',
'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
}
pub_socket.send_json(message, 0)
return message
if __name__ == '__main__':
socket = create_pub_socket()
while True:
print('\n')
print('publisher: ', publish(socket))
time.sleep(1)
sub2.py:
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
socket.bind("tcp://127.0.0.1:9002") # notice
while True:
data = socket.recv_json()
print('second subscriber: ', data)
print('\n')
操作级差,有none.
设置视角差异-.bind()
方法不用知道实际地址(使用 wildcard-expansio 技巧等),.connect()
方法 必须知道 它将开始尝试 .connect()
-to 的目标地址。
Transport-class/可扩展的正式通信模式原型 - 在某些情况下,某些实例化/成为 RTO 的顺序对于适当的原型服务是强制性的,因此,是的,存在差异,其中之一,.bind()
必须更早成为 RTO,在任何远程 .connect()
可能有机会成功之前。
可用于配置 .bind()
端的附加组件特定功能 - 是最后一组主要差异,其中一些较新的 ZeroMQ API 版本3.2+ 开始为 .bind()
端节点添加一些新的访问控制和类似的防御选项,以便在进入 public 互联网暴露的作案手法时帮助管理过多的风险。
这里没有区别(单个发布者和订阅者),但在其他场景(多个发布者或订阅者)中,根据您的策略有区别:
- 即假设有两个客户端 (Machine1, Machine2) 和一个 Server.
每个客户端必须使用 ZMQ
发布数据,并且 Server 必须从 Machine1[=69= 订阅该数据] 和 Machine2:
Machine1 --> 有一个 publisher(有 .connect(Server IP)
)
Machine2 --> 有一个 发布者(有 .connect(Server IP)
)
服务器 --> 有一个 订阅者(有 .bind(Server IP/Self IP)
)
如您所见,在上述场景中我们使用了问题中的第二种情况。
- 然而,如果我们有两个订阅者和一个发布者,我们必须将
.bind()
方法放在发布者中,并将 .connect()
方法放在订阅者中(问题中的第一种情况)。
[注意]:
.bind()
方法不支持localhost
作为IP,而.connect()
方法可以连接到每个IP地址在 .bind()
方法中定义:Why doesn't zeromq work on localhost?
这里是另一个改变.bind()
和.connect()
的例子定位:This-Link
在PythonZMQpublisher/subscriber示例模板中,发布者使用.bind()
方法和订户使用 .connect()
连接到绑定 IP 地址的方法。
但是我们可以将.bind()
和.connect()
互相替换。
我的问题是下面确定的两种情况有什么区别?
(在这些情况下,两个脚本都可以正常工作)
第一种情况,默认为:
pub1.py:
import zmq
import time
from datetime import datetime
def create_pub_socket():
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://127.0.0.1:9002") # notice
return socket
def publish(pub_socket):
message = {
'data': 'hi my name is benyamin',
'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
}
pub_socket.send_json(message, 0)
return message
if __name__ == '__main__':
socket = create_pub_socket()
while True:
print('\n')
print('publisher: ', publish(socket))
time.sleep(1)
sub1.py:
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
socket.connect("tcp://127.0.0.1:9002") # notice
while True:
data = socket.recv_json()
print('subscriber: ', data)
print('\n')
第二种情况,作为修改后的设置,颠倒了 .connect()
和 .bind()
方法的使用:
pub2.py:
import zmq
import time
from datetime import datetime
def create_pub_socket():
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.connect("tcp://127.0.0.1:9002") # notice
return socket
def publish(pub_socket):
message = {
'data': 'hi my name is benyamin',
'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')
}
pub_socket.send_json(message, 0)
return message
if __name__ == '__main__':
socket = create_pub_socket()
while True:
print('\n')
print('publisher: ', publish(socket))
time.sleep(1)
sub2.py:
import zmq
if __name__ == '__main__':
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.setsockopt(zmq.SUBSCRIBE, "")
socket.bind("tcp://127.0.0.1:9002") # notice
while True:
data = socket.recv_json()
print('second subscriber: ', data)
print('\n')
操作级差,有none.
设置视角差异-.bind()
方法不用知道实际地址(使用 wildcard-expansio 技巧等),.connect()
方法 必须知道 它将开始尝试 .connect()
-to 的目标地址。
Transport-class/可扩展的正式通信模式原型 - 在某些情况下,某些实例化/成为 RTO 的顺序对于适当的原型服务是强制性的,因此,是的,存在差异,其中之一,.bind()
必须更早成为 RTO,在任何远程 .connect()
可能有机会成功之前。
可用于配置 .bind()
端的附加组件特定功能 - 是最后一组主要差异,其中一些较新的 ZeroMQ API 版本3.2+ 开始为 .bind()
端节点添加一些新的访问控制和类似的防御选项,以便在进入 public 互联网暴露的作案手法时帮助管理过多的风险。
这里没有区别(单个发布者和订阅者),但在其他场景(多个发布者或订阅者)中,根据您的策略有区别:
- 即假设有两个客户端 (Machine1, Machine2) 和一个 Server.
每个客户端必须使用ZMQ
发布数据,并且 Server 必须从 Machine1[=69= 订阅该数据] 和 Machine2:
Machine1 --> 有一个 publisher(有
.connect(Server IP)
)Machine2 --> 有一个 发布者(有
.connect(Server IP)
)服务器 --> 有一个 订阅者(有
.bind(Server IP/Self IP)
)
如您所见,在上述场景中我们使用了问题中的第二种情况。
- 然而,如果我们有两个订阅者和一个发布者,我们必须将
.bind()
方法放在发布者中,并将.connect()
方法放在订阅者中(问题中的第一种情况)。
[注意]:
.bind()
方法不支持localhost
作为IP,而.connect()
方法可以连接到每个IP地址在.bind()
方法中定义:Why doesn't zeromq work on localhost?这里是另一个改变
.bind()
和.connect()
的例子定位:This-Link