Завершение бесконечного цикла для бота

Я создал чат-бота для Twitch IRC, я могу подключаться и создавать команды и т. д. и т. д., однако я не могу использовать прерывание клавиатуры в командной строке. Я подозреваю, что это потому, что он застрял в этом бесконечном цикле, и я не знаю, как это исправить? Я новичок в программировании кстати!

Вот код, который у меня есть в моем Run.py, openSocket() определен в другом файле, в основном подключение к серверу. s = socket.socket. Первая часть цикла while в основном просто читает сообщения сервера, я думаю, это довольно просто для вас, ребята!

s = openSocket()
joinRoom(s)
readbuffer = ""

while True:
        readbuffer = readbuffer + s.recv(1024).decode("utf-8")
        temp = str.split(readbuffer, "\n")
        readbuffer = temp.pop()

        for line in temp:
            if "PING" in line:
                s.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
                print("---SENT PONG---")
            printMessage(getUser, getMessage, line)
            message = getMessage(line)

            for key in commands:
                command = key
                if command in message:
                    sendMessage(s, commands[command])

((Редактировать: у меня также есть эта проблема, когда соединение с сервером по какой-то причине истекает. Мне удалось заставить его поддерживать соединение с ping/pong в течение примерно 40-45 минут, но затем оно снова отключилось.

РЕДАКТИРОВАТЬ:

Извините, исходный пост был очень грязным. Я создал этот pastebin с наименьшим количеством кода, который мог бы использовать для воссоздания проблемы. Если чат IRC неактивен, он отключится, и я не могу заставить его отправить 2 пинга подряд без каких-либо сообщений между ними, не уверен, что это из-за того, что он отключается перед 2-м пингом или из-за 2-го пинга.

По крайней мере, один раз он отключился еще до того, как я получил первый пинг с сервера.

Пастебин: pastebin.com/sXUW50sS


person imroroyo    schedule 23.09.2016    source источник
comment
Используете ли вы многопоточность, возможно, неявно в joinRoom? Сигналами можно убить только основной поток.   -  person MisterMiyagi    schedule 23.09.2016
comment
pastebin.com/b3h2Y9BE здесь вы можете увидеть все функции, которые я использовал для подключения к серверу!   -  person imroroyo    schedule 23.09.2016
comment
Это не особенно полезно. Попробуйте создать минимальный пример. Вы уверены, что ваш цикл действительно продвигается? Если в сокете недостаточно данных, запрос фиксированного размера (s.recv(1024)) приведет к блокировке. Это блокирующий системный вызов, который вы не можете прервать изнутри python. Это также объяснило бы ваш тайм-аут.   -  person MisterMiyagi    schedule 23.09.2016
comment
На самом деле я не совсем уверен ни в чем, продвигается ли он или как исправить эту потенциальную проблему с помощью (s.recv(1024)). Я такой новичок, и весь этот раздел бота был просто тем, что я хотел пройти, чтобы я мог практиковать более простые вещи. Я мог бы попытаться дать вам более полезную ссылку, но я очень не уверен, что в нее включить. Я могу просто попытаться сделать один, включающий все части, которые имеют отношение к соединению, я думаю..   -  person imroroyo    schedule 23.09.2016
comment
pastebin.com/sXUW50sS Извините за поздний ответ, это наименьшее количество кода, которое мне нужно для воссоздания проблема. Бот продолжает отключаться, даже если он отправляет PONG, хотя это происходит только в том случае, если чат неактивен, если люди активно общаются, все в порядке. Я также не могу легко выйти из бота в командной строке, мне приходится все закрывать, так как он застрял в цикле.   -  person imroroyo    schedule 24.09.2016
comment
Видите ли вы какие-либо из этих операторов отладки print до возникновения проблемы? Я действительно ставлю на s.recv блокировку, потому что данных нет. Если вы хотите покопаться в этом, взгляните на HOWTO сокета Python . В нем есть раздел о том, как длина сообщения может привести к вашей ситуации и как с этим справиться.   -  person MisterMiyagi    schedule 30.09.2016


Ответы (1)


Часть кода, который вы разместили, не имеет большого отношения к описанной вами проблеме.

Это предположение (хотя и обоснованное). В вашем сокет-соединении вы, вероятно, используете try: except: и используете подход Pokemon (должен поймать их всех)

Здесь нужно найти строку, в которой вы делаете что-то вроде этого:

except:
    pass

и измените его на:

except (KeyboardInterrupt, SystemExit):
    raise
except:
    pass

Очевидно, я не пытаюсь сказать, что ваша программа должна перехватывать все исключения и просто проходить, как будто ничего не произошло. Суть в том, что вы, вероятно, уже делаете это (по причинам, которые я не понимаю), и у вас должен быть особый подход к системным ошибкам.

person Tomasz Plaskota    schedule 23.09.2016
comment
KeyboardInterrupt не расширяет Exception, поэтому except Exception: pass все равно должен поймать все, но пусть Ctrl-C поднимается. - person Holloway; 23.09.2016
comment
pastebin.com/b3h2Y9BE здесь вы можете увидеть весь мой файл INIT, в котором определена функция openSocket(). Как я уже сказал, я новичок, и я следил за каким-то парнем на YouTube, когда делал эту часть, так как это немного выше моего уровня. - person imroroyo; 23.09.2016