简体   繁体   English

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

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

I'm building a simple HTTP web service, but I want to send information trough a websocket to another server. 我正在构建一个简单的HTTP Web服务,但我想通过websocket将信息发送到另一台服务器。

For instance when the web service receive a request on /foo , it send on the websocket "request on /foo received" . 例如,当Web服务在/foo上收到请求时,它会在websocket "request on /foo received"发送"request on /foo received"

I'm fairly new to async programming in Python. 我对Python中的异步编程很新。 I choose aiohttp for this, but it's not a hard requirement. 我为此选择了aiohttp ,但这并不是一项艰难的要求。

I have some prior experience with websocket and autobahn and I tried at first to mix aiohtpp and autobahn . 我有一些关于websocket和autobahn经验,我首先尝试混合aiohtppautobahn I even found an example with both but it used wamp and I just want websocket. 我甚至找到了两个例子但它使用了wamp而我只想要websocket。

Then I tried without autobahn as aiohttp handle websocket. 然后我尝试没有autobahn作为aiohttp处理websocket。

My last attempt looks like that: 我最后的尝试看起来像这样:

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)

When requesting / it cashes with the following exception: AttributeError: 'Application' object has no attribute 'ws' 当请求/它兑现以下异常时: AttributeError: 'Application' object has no attribute 'ws'

How can I mix http serving and writing on websocket as a client? 如何将http服务和websocket作为客户端混合使用? Is it even possible ? 它甚至可能吗?

Sometimes a good night of sleep is all you need... 有时你需要一个良好的睡眠之夜......

Basically I needed to initialize a resource and use it in the handlers. 基本上我需要初始化资源并在处理程序中使用它。 Exactly like you would do for a database connection. 与您为数据库连接完全一样。

I used this demo as an example and adapted it to my need. 我以此演示为例,并根据我的需要进行了调整。 Here is what it looks like: 这是它的样子:

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)

I hope this can help other asyncio / aiohttp beginners. 我希望这可以帮助其他asyncio / aiohttp初学者。

Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM