【问题标题】:Python3 and asyncio: how to implement websocket server as asyncio instance?Python3 和 asyncio:如何将 websocket 服务器实现为 asyncio 实例?
【发布时间】:2019-07-06 03:21:24
【问题描述】:

我有多个服务器,每个服务器都是由 asyncio.start_server 返回的实例。我需要我的 web_server 与 websockets 一起使用,以便有可能使用我的 javascript 客户端获取数据。如我所见,asyncio 不提供 websockets,只提供 tcp 套接字。也许我错过了什么?我想实现可以在 asyncio.gather 中使用的 websocket 服务器,如下所示:

    loop = asyncio.get_event_loop()

    login_server = LoginServer.create()
    world_server = WorldServer.create()
    web_server   = WebServer.create()

    loop.run_until_complete(
        asyncio.gather(
            login_server.get_instance(),
            world_server.get_instance(),
            web_server.get_instance()
        )
    )

    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

    loop.close()

我不想使用 aiohttp,因为如果在上面的代码中使用类似 aiohttp 只是阻止了其他任务。我需要一些非阻塞的东西,并且可以访问其他服务器(登录和世界)的数据。 asyncio 可以吗? asyncio 是否提供类似 websockets 的东西?如何在 asyncio.gather 中实现 websocket 服务器?

【问题讨论】:

    标签: python python-3.x websocket python-3.5 python-asyncio


    【解决方案1】:

    好吧,最后我已经实现了 WebServer,以便在另一个带有 asyncio 的线程中使用。代码(WebServer代码):

    from aiohttp import web
    
    
    class WebServer(BaseServer):
    
        def __init__(self, host, port):
            super().__init__(host, port)
    
        @staticmethod
        async def handle_connection(self, request: web.web_request):
            ws = web.WebSocketResponse()
            await ws.prepare(request)
    
            async for msg in ws:
                Logger.debug('[Web Server]: {}'.format(msg))
    
            return ws
    
        @staticmethod
        def run():
            app = web.Application()
            web.run_app(app, host=Connection.WEB_SERVER_HOST.value, port=Connection.WEB_SERVER_PORT.value)
    

    以及如何运行:

    executor = ProcessPoolExecutor()
    
    loop.run_until_complete(
        asyncio.gather(
            login_server.get_instance(),
            world_server.get_instance(),
            loop.run_in_executor(executor, WebServer.run)
        )
    )
    

    【讨论】:

    • 运行 web.run_apprun_in_executor 是一种反模式,因为它(不必要地)运行 两个 事件循环。您可以改用AppRunner API,如this answer的第一个代码sn-p所示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2016-09-19
    • 2021-10-15
    相关资源
    最近更新 更多