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

时间:2019-06-12 15:48:35

标签: python websocket aiohttp

我正在构建一个简单的HTTP Web服务,但是我想通过websocket将信息发送到另一台服务器。

例如,当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'

我如何将HTTP服务和在websocket上作为客户端的服务混合使用? 甚至有可能吗?

1 个答案:

答案 0 :(得分:0)

有时您需要一个良好的睡眠...

基本上,我需要初始化资源并在处理程序中使用它。 就像您要进行数据库连接一样。

我以这个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初学者。

欢呼

相关问题