Я использую pyzmq в своем приложении qt.
Я нашел какое-то прошлое решение в списке рассылки в первая ссылка .Итак, вот мой код со ссылкой.
import zmq
from PyQt5.QtCore import QSocketNotifier
from PyQt5.QtWidgets import QApplication, QWidget
class ChatApp(QWidget):
def __init__(self):
super(ChatApp, self).__init__()
self._zmq_context = zmq.Context()
self._zmq_sock = self._zmq_context.socket(zmq.SUB)
self._zmq_sock.connect("tcp://localhost:5556")
self._zmq_sock.setsockopt(zmq.SUBSCRIBE, b"bm_chat")
self.read_noti = QSocketNotifier(self._zmq_sock.getsockopt(zmq.FD),
QSocketNotifier.Read,
self)
self.read_noti.activated.connect(self.on_read_msg)
def on_read_msg(self, _):
self.read_noti.setEnabled(False)
flags = self._zmq_sock.getsockopt(zmq.EVENTS)
if flags & zmq.POLLIN:
msg = self._zmq_sock.recv_multipart()
topic = msg[0]
data = msg[1]
print(topic, data)
elif flags & zmq.POLLOUT:
print("[Socket] zmq.POLLOUT")
elif flags & zmq.POLLERR:
print("[Socket] zmq.POLLERR")
else:
print("[Socket] FAILURE")
self.read_noti.setEnabled(True)
if __name__ == '__main__':
app = QApplication([])
win = ChatApp()
win.show()
app.exec_()
Но, как и следовало ожидать, после того, как сообщение сработало один раз, и никогда не произошло снова.Это мое сообщение
[Socket] FAILURE
b'bm_trade' b'hello0'
Поэтому я искал другие решения здесь , с чтением self._zmq_sock.getsockopt (zmq.EVENTS) после включения уведомления qt.Поэтому я изменил свой код в последней строке
def on_read_msg(self, _):
self.read_noti.setEnabled(False)
flags = self._zmq_sock.getsockopt(zmq.EVENTS)
if flags & zmq.POLLIN:
msg = self._zmq_sock.recv_multipart()
topic = msg[0]
data = msg[1]
print(topic, data)
elif flags & zmq.POLLOUT:
print("[Socket] zmq.POLLOUT")
elif flags & zmq.POLLERR:
print("[Socket] zmq.POLLERR")
else:
print("[Socket] FAILURE")
self.read_noti.setEnabled(True)
self._zmq_sock.getsockopt(zmq.EVENTS) // Here is fixed
Он прекрасно работает, пока скорость передачи данных не станет низкой.Вот код моего PUB-сервера.
from time import sleep
import zmq
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5557")
def ms(millisec):
return millisec / 1000
if __name__ == '__main__':
count = 0
while True:
socket.send_multipart(
[b'bm_trade', bytes(('hello' + str(count)).encode('utf-8'))])
count += 1
sleep(ms(10))
Этот трюк работает только на промежутке времени события более 10 мс.Если вы измените sleep (ms ()) до 10, клиентская сторона также будет запущена один раз и никогда не будет срабатывать.
Кто-то скажет, что все в порядке, но в моем приложении задержка очень низкая, и все сообщения всегда должны быть видныв графическом интерфейсе.
Почему возникла эта проблема, как ее решить?