Добрый день, решил попробовать поюзать aiohttp для вэбсокетов. Нашел примеры реализации простого сервера, с этим все более менее понятно. Но есть потребность работы в связке с RabbitMQ. Нашел aiopika. Запуск тестовых примеров, подключение, примем, отправка сообщений - все работает. Но как теперь подружить их вместе?
Как я вижу подобную реализацию: 1. До начала работы сервера нужно создать подключение к RabbitMQ, чтобы потом этот коннектор можно было передавать в другие таски. 2. Пример работы с вэбсокетами: https://github.com/samael500/aiochat/blob/master/aiochat/chat/views.py Класс (WebSocket) Тут в методе Get обрабатывается новое подключение клиента, один экземпляр этого класса - один клиент. 3. В этом же методе Get мне надо создать очередь и подписаться на нее (для каждого клиента создается отдельная очередь). 4. Слушать сообщения из очереди в этом методе не получится, т.к он слушает входящие данные по вэб сокетам, поэтому создаем таск, в котором будем слушать сообщения из очереди.
#########
if self.room.id not in app.wslist:
app.wslist[self.room.id] = {}
# генерируем имя очереди
queue_name = uuid.uuid()
asyncio.create_task(create_queue(queue_name))
message = await app.objects.create(
Message, room=self.room, user=None, text=f'@{user.username} join chat room')
#######
И сам таск create_queue:
async create_queue(queue_name):
# Creating channel
channel = await connection.channel() # type: aio_pika.Channel
# Declaring queue
queue = await channel.declare_queue(
queue_name,
auto_delete=True
) # type: aio_pika.Queue
async for message in queue:
with message.process():
print(message.body)
И столкнулся со следующими вопросами: 1. По идее нам нужен один коннект к RabbitMQ на весь сервер, поэтому до запуска сервера мы должны подключиться к RabbitMQ и потом этот коннектор передавать в таск create_queue. Верно? Но сам метод библиотеки aiopika должен вызываться в сопрограмме, например метод из либы aiohttp для получения сессии можно вызвать с помощью async with, тогда мы получаем коннектор, который спокойно можем передавать в другие сопрограммы, но вот как быть с aiopika? 2. Передача сообщения полученного в RabbitMQ в объект вэб сокета (класс WebSocket). В методе get мы просто создали и запустили таск, который будет слушать сообщения, но как он может оповещать клиента о получении сообщения? Коллбек? Но в asyncio подходе на сколько я понял коллбки это моветон.
С asyncio начал разбираться совсем не давно, учебные примеры, который встречаются в инете направленны, по сути, только на асинхронное получение данных с разных сайтов, в общем, рассматривают только одинаковые задачи, запущенные в разных сопрограммах.