如何在 aiohttp 请求处理程序中通过客户端 websocket 发送数据

How to send data through a client websocket in a aiohttp request handler

我正在构建一个简单的 HTTP 网络服务,但我想通过网络套接字将信息发送到另一台服务器。

例如,当 Web 服务在 /foo 上收到请求时,它会在 websocket "request on /foo received".

上发送

我对 Python 中的异步编程相当陌生。 我为此选择 aiohttp,但这不是硬性要求。

我之前有一些使用 websocket 和 autobahn 的经验,我一开始尝试混合使用 aiohtppautobahn。 我什至找到了一个 example ,但它使用了 wamp 而我只想要 websocket.

然后我尝试不使用 autobahn 作为 aiohttp 处理 websocket。

我最后一次尝试是这样的:

from aiohttp import web, ClientSession, WSMsgType

async def callback(msg):
    print(msg)

async def websocket(session):
    async with session.ws_connect('http://localhost:8000') as ws:
        app['ws'] = ws
        async for msg in ws:
            if msg.type == WSMsgType.TEXT:
                await callback(msg.data)
            elif msg.type == WSMsgType.CLOSED:
                break
            elif msg.type == WSMsgType.ERROR:
                break

async def hello(request):
    app.ws.send_str('{"hello": "world"}')
    return web.Response(text="Hello, world")

async def init(app):
    session = ClientSession()
    app['websocket_task'] = app.loop.create_task(websocket(session))

app = web.Application()
app.add_routes([web.get('/', hello)])
app.on_startup.append(init)
web.run_app(app, port=7000)

当请求 / 时,它会兑现,但有以下例外情况: AttributeError: 'Application' object has no attribute 'ws'

作为客户端,我如何在 websocket 上混合使用 http 服务和写入? 有可能吗?

有时候,睡个好觉就是您所需要的...

基本上我需要初始化资源并在处理程序中使用它。 就像您对数据库连接所做的那样。

我以这个 demo 为例,并根据我的需要对其进行了调整。 这是它的样子:

from aiohttp import web, ClientSession

class Handler:
    def __init__(self, ws):
        self._ws = ws

    async def hello(self):
        await self._ws.send_str('{"hello": "world"}')
        return web.Response(text="Hello, world")

async def init(app):
    session = ClientSession()
    ws = await session.ws_connect('http://localhost:8000')
    h = Handler(ws)
    app.add_routes([web.get('/', h.hello)])

app = web.Application()
app.on_startup.append(init)
web.run_app(app, port=7000)

我希望这可以帮助其他 asyncio/aiohttp 初学者。

干杯