Как отправить данные через клиентский веб-сокет в обработчике запросов aiohttp - PullRequest
0 голосов
/ 12 июня 2019

Я создаю простой HTTP-веб-сервис, но хочу отправить информацию через веб-сокет на другой сервер.

Например, когда веб-сервис получает запрос на /foo, он отправляет наwebsocket "request on /foo received".

Я довольно новичок в асинхронном программировании на Python.Я выбираю aiohttp для этого, но это не сложное требование.

У меня есть некоторый предыдущий опыт работы с websocket и autobahn, и я сначала попытался смешать aiohtpp и autobahn.Я даже нашел пример с обоими, но он использовал wamp, и я просто хочу веб-сокет.

Затем я попытался без autobahn как aiohttp обрабатывать веб-сокет.

Моя последняя попытка выглядит следующим образом:

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 и запись на веб-сокете какклиент?Это вообще возможно?

1 Ответ

0 голосов
/ 13 июня 2019

Иногда хороший сон - это все, что тебе нужно ...

В основном мне нужно было инициализировать ресурс и использовать его в обработчиках. Точно так же, как вы бы сделали для подключения к базе данных.

Я использовал это демо в качестве примера и адаптировал его под свои нужды. Вот как это выглядит:

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 новичкам.

Приветствия

...