asyncio“未来属于与指定为循环参数的循环不同的循环”

2024-10-01 13:25:31 发布

您现在位置:Python中文网/ 问答频道 /正文

最近,我一直在试图弄清楚Python中的异步处理,但似乎无法理解它的结构方式。我已经习惯了Java实现的系统,基本上你可以用runnables做任何你想做的事情,而且它可以正常工作。你知道吗

基本上,我想创建一个同时运行Flask和另一个websocket服务器的应用程序,并使用Flask作为服务器和活动连接的控制面板(有点像仪表板)。我设法让这两个进程运行,但现在需要直接调用异步函数,但似乎不能这样做。你知道吗

我有一个控制器类处理传入连接,如下所示:

class SessionController:
    app_controller = None
    app = None
    sessions = dict()

    def __init__(self, app_controller: 'AppController'):
        self.app_controller = app_controller

    async def start(self):
        self.app = await websockets.serve(
            self.connect,
            '0.0.0.0',
            8887,
            subprotocols=[Subprotocol('ocpp1.6')]
        )
        await self.app.wait_closed()

    async def connect(self, websocket, path):
        point_id = str(uuid.uuid1())
        cp = Session(point_id, websocket)
        try:
            self.register(cp)
            await cp.start()
        except ConnectionClosedError:
            print("Connection reset")
        finally:
            self.unregister(cp)

    def register(self, cp):
        print("Client {0}:{1}#{2} connected".format(cp.websocket.host, cp.websocket.port, cp.point_id))
        self.sessions[cp.charge_point_id] = cp

    def unregister(self, cp):
        print("Client {0}:{1}#{2} disconnected".format(cp.websocket.host, cp.websocket.port, cp.point_id))
        self.sessions.pop(cp.point_id)

    def end_session(self, point_id):
        cp = self.sessions.get(point_id)
        cp.close()
        self.unregister(cp)

现在,当我得到一个连接时,它工作正常,会话被创建并在会话映射中注册。但是当我试图用活动会话的ID调用end\u session时,我得到了错误RuntimeWarning: coroutine 'WebSocketCommonProtocol.close' was never awaited self.websocket.close()。代码仍然正常工作和运行,但最好我不会得到一个错误,当然。你知道吗

在做了一些在线搜索之后,人们建议我尝试asyncio并使用一个循环来运行这个方法。我使用以下代码:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(self.websocket.close())

但这给了我以下错误:The future belongs to a different loop than the one specified as the loop argument

我只是不能理解python处理异步的方式,有没有一种方法可以让我在调用函数时不出错?你知道吗


Tags: selfloopidappclosedef错误await
1条回答
网友
1楼 · 发布于 2024-10-01 13:25:31

首先,如果您想运行一个webserver并同时为websockets提供服务,那么最好使用ASGI服务器,比如FastAPI(https://fastapi.tiangolo.com/)。你知道吗

还要注意,Flask是一个WSGI服务器,它将在一个单独的线程中处理每个请求。如果您使用的是事件循环,则事件循环是线程的本地循环。因此,在组合多线程和事件循环时要小心。你知道吗

我不能准确指出您的问题,因为您的代码示例不包括会话类。你知道吗

相关问题 更多 >