Я пытаюсь написать своего собственного бота на Python для подключения и взаимодействия с Twitch-чатом через его IRC-интерфейс. У меня есть соединение и я могу получать и отправлять данные. Я также отвечаю на входящие запросы PING с помощью PONG (они отправляются примерно через 5 минут). Но примерно через 3 минуты бездействия (так что, прежде чем я даже получу PING), соединение обрывается с
socket.error: [Errno 104] Connection reset by peer
Я использую модуль socket
в Python для соединения. Ошибка возникает, когда метод recv()
вызывается в моем сокете.
Некоторые вещи, которые мне удалось выяснить:
Перед сбоем соединения входящий (без ответа) PING отсутствует.
Время между последним сообщением в чате и отключением швов каждый раз составляет около 3 минут. И достаточно что-то получить (ссылку на чат-сообщение от кого-то другого), чтобы сбросить этот таймер. Мне не нужно ничего отправлять самому.
Сначала я подумал, что у меня истекает время, потому что я ничего не получаю слишком долго. Похоже, это не так, потому что, если я установлю меньшее время ожидания для socket.recv()
, я получу socket.timeout: timed out
, а не ошибку, показанную выше.
Я думаю, что не пропускаю никаких данных, отправленных мне, потому что все сообщения чата приходят. Но я публикую свой основной цикл для получения данных ниже, чтобы быть уверенным.
Теперь мой вопрос: почему соединение не работает и как я могу это предотвратить?
У меня такое чувство, что это расплывчатый вопрос. Это первый раз, когда я пытаюсь работать с интерфейсом IRC, и я не знаю, как получить больше информации о том, в чем именно заключается проблема.
На всякий случай вот сетевая петля, которую я использую для приема данных. Я думаю, что это работает нормально, потому что все сообщения чата проходят. Но, возможно, есть ошибка, и я пропускаю некоторые входящие данные (например, PING).
readbuffer = ''
while True:
readbuffer = readbuffer + s.recv(1024)
temp = string.split(readbuffer, '\n')
readbuffer = temp.pop()
for line in temp:
print(line)
# PING/PONG
if "PING :tmi.twitch.tv" in line:
print("PONG :tmi.twitch.tv")
s.send(line.replace('PING', 'PONG'))
Здесь s
— это socket()
форма модуля socket
.
Похоже, это работает. Я просто отправляю тот же самый PING, который я получаю от сервера. Я не получаю обратно PONG, но это не проблема. Это "правильный" поступок или не имеет значения, что я отправляю?
Пингование сервера каждые 2 минуты решило проблему. Я просто добавил эту функцию
import time, threading
def sendPing(s):
print('sending PING')
s.send("PING :tmi.twitch.tv")
threading.Timer(120, sendPing, [s]).start()
sendPing(s)
перед основным циклом.
Спасибо болтовня за подсказку.
Вы пытались сделать так, чтобы вы отправляли PONG каждые, скажем, 2 минуты, даже если вы не получили пинг?