结合 asyncio websockets 和 QThread

问题描述 投票:0回答:0

我有一个 pyqt 应用程序,它必须通过 websockets 与客户端通信。我设法在 qt 环境之外的 python 脚本中创建服务器,但是当我包含 asyncio.run 时,它冻结了 qt 应用程序。因此我尝试创建一个继承的 QThread 类来处理 websocket 函数:

class WSThread(QThread):
    def __init__(self, port, loop, parent=None):
        super(WSThread, self).__init__(parent)
        self.clients = []
        self.port = port
        self.loop = loop

    def run(self):
        server = websockets.serve(self.handler, "", self.port)
        self.loop.run_until_complete(server)
        self.loop.run_forever()

    # async def start_server(self):
    #     await self.server.wait_closed()

    async def send(self, websocket, message):
        try:
            await websocket.send(message)
        except websockets.ConnectionClosed:
            pass

    async def broadcast(self, message):
        if self.clients:  # asyncio.wait doesn't accept an empty list
            await asyncio.wait([
                asyncio.create_task(self.send(websocket, message))
                for websocket in self.clients
            ])

    async def handler(self, websocket, path):
        self.clients.append(websocket)
        async for message in websocket:
            await self.broadcast(message)

目标是将服务器上收到的消息传输给所有连接的客户端。我的代码肯定不是最优的,但它与 Qt 分开工作。

我在这样的 QDialog 类中使用它:

class MyDialog(QDialog)
    def __init__(self, parent=None):
        super(MyDialog, self).__init__(parent)
        tb = QPushButton()
        tb.setText("Start WS")
        tb.clicked.connect(self.start_ws)
        self.layout = QVBoxLayout()
        self.layout.addWidget(tb)
        self.setLayout(self.layout)

    def start_ws(self):
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop = asyncio.get_event_loop()
        ws = WSThread(WS_PORT, loop)
        ws.start()

dlg = MyDialog()
dlg.show()

但是我收到一条错误消息:

RuntimeError: There is no current event loop in thread 'Dummy-3'.
。我不理解这条消息,因为我正在创建循环并将其作为参数传递给线程类。

websocket pyqt python-asyncio qthread event-loop
© www.soinside.com 2019 - 2024. All rights reserved.