Python GUI 未捕获 zeromq 消息

Posted

技术标签:

【中文标题】Python GUI 未捕获 zeromq 消息【英文标题】:Python GUI not capturing zeromq message 【发布时间】:2015-05-30 12:16:12 【问题描述】:

我有一个小程序,没有收到来自服务器的响应。 这是在 Ubuntu 14.04 上使用 python 3.4 和最新的 zeromq 和 pyqt5。 客户端 GUI 向服务器发送一条消息,服务器获取并响应,但客户端看不到响应。

代码如下: miniServer.py:

import os
import sys
import time
import zmq
from zmq.eventloop import ioloop
from zmq.eventloop.zmqstream import ZMQStream

# Prepare for client socket
ctx = zmq.Context.instance()
sIn = ctx.socket(zmq.PULL)
urlIn = 'tcp://127.0.0.1:1234'
sIn.bind(urlIn)
# Prepare for sockets to GUI and Web
guiCalled = False
webCalled = False
urlGui = 'tcp://127.0.0.1:2345'
urlWeb = 'tcp://127.0.0.1:3456'
sGUI = None
sWeb = None

def __GetConfig__(sender, data):
    if "GUI" == sender:
        print("Sending back config list to GUI")
        sGUI.send_string("From Server to GUI")
    elif "WEB" == sender:
        sWeb.send_string("From Server to Web")
def __CheckGUICalled__():
    # Used to only connnect once
    global guiCalled
    global sGUI
    if not guiCalled:
        print("Connected to client GUI at port 2345")
        guiCalled = True
        sGUI = ctx.socket(zmq.PUSH)
        sGUI.connect(urlGui)
def __CheckWebCalled__():
    # Used to only connnect once
    global webCalled
    global sWeb
    if not webCalled:
        webCalled = True
        sWeb = ctx.socket(zmq.PUSH)
        sWeb.connect(urlWeb)

actions = 
    "GET_CONFIG": __GetConfig__
clients = 
    "GUI": __CheckGUICalled__,
    "WEB": __CheckWebCalled__

def check_msg(msg):
    newStr = msg[0].decode("utf-8", "strict")
    if newStr.count(":") == 2:
        [sender, command, data] = newStr.split(":")
        print("Sender: " + sender + ", Command: " + command + ", Data: " + data)
        # connect if not already done
        clients.get(sender, lambda: None)()
        # execute the command sent from client
        actions.get(command, lambda: None)(sender, data)

# register the check_msg callback to be fired
# whenever there is a message on our socket
stream = ZMQStream(sIn)
stream.on_recv(check_msg)

# Setup callback handling the XMOS
tic = time.time()
def xmos_handler():
    # just testing
    print("Loop time: %.3f" % (time.time() - tic))

pc = ioloop.PeriodicCallback(xmos_handler, 200)
pc.start()

# start the eventloop
ioloop.IOLoop.instance().start()

miniGUI.py:

import os
import sys
import zmq
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from zmq.eventloop.zmqstream import ZMQStream

# prepare out socket to server
ctx = zmq.Context.instance()
sOut = ctx.socket(zmq.PUSH)
sOut.connect('tcp://127.0.0.1:1234')

# handle inputs from server
def check_msg(msg):
    newStr = msg[0].decode("utf-8", "strict")
    print("Message: " + newStr + " received")
sIn = ctx.socket(zmq.PULL)
sIn.bind('tcp://127.0.0.1:2345')
stream = ZMQStream(sIn)
stream.on_recv(check_msg)

# setup window
class Form(QWidget):
    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        nameLabel = QLabel("Name:")
        self.nameLine = QLineEdit()
        self.submitButton = QPushButton("Submit")
        buttonLayout1 = QVBoxLayout()
        buttonLayout1.addWidget(nameLabel)
        buttonLayout1.addWidget(self.nameLine)
        buttonLayout1.addWidget(self.submitButton)
        self.submitButton.clicked.connect(self.submitContact)
        mainLayout = QGridLayout()
        mainLayout.addLayout(buttonLayout1, 0, 1)
        self.setLayout(mainLayout)
        self.setWindowTitle("For Test: GUI:GET_CONFIG:0")

    def submitContact(self):
        name = self.nameLine.text()
        sOut.send_string(name)
        print("Message " + name + " sent")

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    screen = Form()
    screen.show()
    sys.exit(app.exec_())

先启动服务器:

python3.4 miniServer.py

然后是 GUI:

python3.4 miniGUI.py

在编辑小部件中写入字符串:

GUI:GET_CONFIG:0

然后按下提交按钮将在服务器控制台上打印:

发送者:GUI,命令:GET_CONFIG,数据:0

在端口 2345 连接到客户端 GUI

将配置列表发送回 GUI

并且仅在 GUI 控制台上

消息 GUI:GET_CONFIG:0 已发送

写出来,而预期的结果应该是:

消息 GUI:GET_CONFIG:0 已发送

消息:从服务器到 GUI 收到

我做错了什么?

【问题讨论】:

【参考方案1】:

解决方案是使用套接字类型 REQ/REP 而不是 PUSH/PULL,这使得代码也更加简洁。

【讨论】:

以上是关于Python GUI 未捕获 zeromq 消息的主要内容,如果未能解决你的问题,请参考以下文章

ZeroMQ 非阻塞非队列推送

zeromq 学习和python实战

如何使用 ZeroMQ 从 C# 客户端向 C++ 服务器发送消息

使用ZeroMq源测试Kuiper吞吐量

未捕获的异常“PDOException”消息“无效的数据源名称”

未捕获的异常“RuntimeException”,消息“无法写入缓存目录”