LINUX.ORG.RU

Помогите разобраться в Asyncio.

 ,


0

1

Добрый день, решил попробовать поюзать 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 начал разбираться совсем не давно, учебные примеры, который встречаются в инете направленны, по сути, только на асинхронное получение данных с разных сайтов, в общем, рассматривают только одинаковые задачи, запущенные в разных сопрограммах.

Ответ на: комментарий от pawnhearts

Да, сейчас как раз наткнулся на доку: https://docs.aiohttp.org/en/stable/web_advanced.html#background-tasks

Но там у Redis слушают все сообщения, которые потом сразу отправляют по сокетам. Но с помощью метода app.on_startup.append я могу создать таск, в котором будет производиться подключение к RabbitMQ и полученный коннектор я как раз и смогу передавать в таск create_queue. В общем, оправдано ли такое решение?

hell_wood ()

оффтопну:
мда, вот поэтому я непротив второго питона как «первого языка» для новичка, но против чтобы им становился третий питон. синтаксический сахар - это здорово, когда ты понимаешь что тамся делает под капотом и используешь его по прямому назначению. а вот так - это трындец. пожалуй этоже относится и к IDE типа всяких пайчармов

genryRar ★★ ()
Ответ на: комментарий от genryRar

Ты наивно думаешь, что писать на сишечке с

libuv + rabbitmq + c-ares
проще и «понятней»? Поверь, там такая же «помойка», и куча либ пишется на своих реализациях «event loop», и т.п., геммора порой даже больше, а уж дебаг ваще то ещё развлечение, т.ч. питон вполне нормальная обертка над сишкой, и пакетов на любой чих достаточно, в любой сфере для питона есть хорошие либы, с которыми удобно стартовать.

menangen ★★★★★ ()
Ответ на: комментарий от menangen

дак я какбэ питон в данном случае именно как пример использовал - раз уж именно он обсуждается в топике. опятьже как пример - второй питон с темже джиевентом по моему опыту работы с джунами не создает в голове такой ядреной каши

genryRar ★★ ()