我在从两台zmq服务器读取消息时遇到问题(一台设置为REQ|REP
,一台设置为PUB|SUB
)
两台服务器正在另一台计算机上运行。当我仅读取REQ|REP
连接时,一切工作正常,但是一旦我也尝试读取PUB|SUB
连接,程序就会冻结(我想它永远等待消息)]
from PyQt5 import QtCore, QtGui, QtWidgets
import zmq
import ui_mainwindow
class MainWindow(QtWidgets.QMainWindow, ui_mainwindow.Ui_MainWindow):
def __init__(self, parent = None):
super(MainWindow, self).__init__(parent)
self.context = zmq.Context()
try:
self.stateSocket = self.context.socket(zmq.REQ)
self.stateSocket.connect("tcp://134.105.89.197:5555")
except zmq.ZMQError as e:
print('States setup failed: ', e)
try:
self.context = zmq.Context()
self.anglesSocket = self.context.socket(zmq.SUB)
self.anglesSocket.connect("tcp://134.105.89.197:5556")
except zmq.ZMQError as e:
print('angles setup failed: ', e)
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.publishState)
self.timer.setInterval(500)
self.timer.start()
self.timer2 = QtCore.QTimer()
self.timer2.timeout.connect(self.publishAngles)
self.timer2.setInterval(500)
self.timer2.start()
# +more variables unrelated to problem
def publishState(self):
request= "a string"
try:
self.stateSocket.send_string(request)
self.reset = 0
message = self.stateSocket.recv()#flags=zmq.NOBLOCK)
values = [float(i) for i in message.decode("UTF-8").split(',')]
print("Status: ", message)
except zmq.ZMQError as e:
print('State communication: ', e)
values = [0] * 100
def publishAngles(self):
try:
message = anglesSocket.recv_string() # flags=zmq.NOBLOCK)
#values = [float(i) for i in message.decode("UTF-8").split(',')]
print("Angles: ", message)
except zmq.ZMQError as e:
print('Angles communication: ', e)
values = [0] * 100
编辑:添加了完整的相关代码。我观察到死锁并非来自REQ|REP
,仅此部分即可正常工作。但是PUB|SUB
部分似乎无法在计时器功能中使用。当我用publishAngels()
中的while循环做一个最小的例子时,它可以工作。
那么,有没有一种在Qt Timer连接的功能中使用PUB|SUB
套接字的好方法?
如果从未使用过ZeroMQ,在这里您可以先看看"ZeroMQ Principles in less than Five Seconds",然后再深入研究更多细节]]
问:“我有没有忽略任何愚蠢的错误?”
是的,有一些而且很容易完善。
1]到目前为止,不完整的可见ZeroMQ部分显示出主要的不确定性,即对SUB
-套接字-Archetype AccessPoint应用什么类型的订阅和其他安全保护设置(如果有),何时何地。除了出于明显原因的与订阅管理相关的设置类型之外,REQ
-套接字-Archetype AccessPoint也是如此。
2)该代码忽略了d
分布式-F iteite-S tate-A utomaton(dFSA)逻辑的已知规则的书面原则,REQ/REP
可扩展的正式沟通原型。请使用正确的逻辑避免这种情况,而不违反REQ-REP-REQ-REP-REQ-REP的此处必填的dFSA步进器,并使REQ
和SUB
处理中的任何一个变得相互独立,并且您拥有。换句话说,忽略zmq.NOBLOCK
标志的使用的简单dFSA规则也无法解决死锁。[如果您真的想成为一名分布式计算专业人员,那么必读的就是神话般的Pieter Hintjen的书“ Code Connected,Volume 1”