Async Twitch chatbot с Python: сокет, asyncio - PullRequest
0 голосов
/ 24 октября 2019

Я работаю над дерганным ботом для моего канала. Синхронная версия бота работает нормально, и я попытался написать простой асинхронный код с двумя задачами: чтение чата и ответ на сообщения.

Я не очень разбираюсь в Python и в частности в asyncio, но, насколько я знаю, я хочу "ожидать" всех операций ввода-вывода.

Проблема в том, чтовторая задача - отвечающая - вообще не выполняется, так как не может получить приоритет, когда задача чтения ожидает получения данных. Кажется, я не понимаю некоторые принципы асинцио. Или может сокет не может работать таким образом? Любая помощь приветствуется.

import socket
import asyncio

HOST = 'irc.twitch.tv'
NICK = 'rezolbot'
PORT = 6667
PASS = 'oauth:jhax3kh2i32vcg0hx00lw11r7mqk0d'
CHAN = 'rezolventa'

s = socket.socket()
mes_q = [] # queue of messages to send

# sync, only for connection
def send_line(line):
    s.send(bytearray(line, 'utf-8'))


# sends a message like it's from the bot in chat
async def send_message(message):
    s.send(bytearray('PRIVMSG #' + CHAN + ' :' + message + '\r\n', 'utf-8'))


# task, sends a message from a queue
async def respond():
    while True:
        if mes_q:
            await send_message(mes_q.pop(0))


async def listen():
    return s.recv(1024).decode('utf-8')


# task parses messages from chat
async def fetch():
    while True:
        #await asyncio.sleep(0.1)
        print('mes_q', mes_q)
        inc = await listen()
        print(inc)
        # append queue with last 3 symbols from incoming message
        mes_q.append('no you ' + inc[-5:-2])


async def main():
    task1 = asyncio.create_task(fetch())
    task2 = asyncio.create_task(respond())
    await asyncio.gather(task1, task2)


if __name__ == '__main__':
    s.connect((HOST, PORT))
    send_line('PASS ' + PASS + '\r\n')
    send_line('NICK ' + NICK + '\r\n')
    send_line('JOIN #' + CHAN + '\r\n')
    asyncio.run(main())

1 Ответ

0 голосов
/ 24 октября 2019

Ваш код не асинхронный. Вы вызываете синхронные функции (Socket.send, ...) из сопрограммы, которая не делает их асинхронными . Сами функции должны быть сопрограммами.

Вот хороший пост, объясняющий, что такое сопрограмма и как она работает

Пример библиотеки, которую вы можете использовать для открытия сокетаподключение к twitch и выполнение асинхронных операций над ним будет websockets .

Если вы хотите писать асинхронные чат-боты в twitch, рассмотрите возможность использования чего-то вроде TwitchIO , чтобы не суетиться вокругс сокетами.

Кроме того: Вы утекли свои учетные данные, рассмотрите возможность их сброса!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...