So my question is, how would i get my bot to listen if there is a PING and if there's no ping in an interval of a minute, it will react as though the connection has been lost. How would one go about doing that?
EDIT:
This is the working code for registering the connection fallout (although having trouble with reconnecting):
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import socket
import string
import os
import platform
import time
# Variables
HOST = "irc.channel.net"
PORT = 6667
NICK = "Botname"
IDENT = "Botname"
REALNAME = os.getenv('USER')
CHAN = "##ChannelName"
readbuffer = ""
# Our IRC connection
irc = socket.socket()
irc.settimeout(300)
connected = False
def connection(host, port, nick, ident, realname, chan):
while connected is False:
try:
irc.connect((host, port))
irc.send("NICK %s\r\n" % nick)
irc.send("USER %s %s bla :%s\r\n" % (ident, host, realname))
irc.send("JOIN :%s\r\n" % chan)
# Initial msg to send when bot connects
irc.send("PRIVMSG %s :%s\r\n" % (chan, "TehBot: "+ nick + " Realname: " + realname + " ."))
global connected
connected = True
except socket.error:
print "Attempting to connect..."
time.sleep(5)
continue
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
while connected:
try:
data = irc.recv ( 4096 )
# If connection is lost
if len(data) == 0:
break
print data
# If Nick is in use
if data.find ( "Nickname is already in use" ) != -1:
NICK = NICK + str(time.time())
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
# Ping Pong so we don't get disconnected
if data[0:4] == "PING":
irc.send ( "PONG " + data.split() [ 1 ] + "\r\n" )
except socket.timeout:
global connected
connected = False
print connected
break
print "Out of loop"
connection(HOST, PORT, NICK, IDENT, REALNAME, CHAN)
There's no reason to do any fancy 'timeout' tricks as long as your connection is still up. If the length of the data returned from
recv
is 0, the TCP connection has been closed.I suspect that recv() can also throw an exception if the connection is not terminated cleanly.
Edit:
I'm not sure what you're trying to accomplish. The IRC server will send you a
PING
occasionally. If you don't respond with aPONG
, then the server will disconnect you. When the server disconnects you, then yourrecv()
call will return a 0-length string.All you have to do is respond to
PING
when you get it, and handle if the connection happens to close.Your logic should look something like this:
Another thing to keep in mind is that you need to buffer any received data until you get a
\r\n
sequence, you will not always get a exactly one complete message at the same time; you might get half of one, or three, or three and a half lines.This will record the time each time it gets a ping, and if it goes too long without one, break out of the
connected
loop. You don't needwhile connected == True:
, justwhile connected:
does the same thing.Also, consider using
connection
instead ofConnection
, it's the Python convention to use capitalized names only for classes.The reason why your having issues reconnecting is because once you do there's no loop to listen to for incoming data once you do, and you'd most likely ping timeout. The connection while loop should look like:
Now when the connection times out you reconnect and begin to listen for incoming data.
NOTE: Now that there's no way for the application to terminate on it's on you have to either [Ctrl]+[C] in the command line, or construct a "!quit" type command to close the socket and the application... socket first, of course.
You should not use
data.find('PING')
because it also finds "PING" in other messages. And then you send an incorrect PONG...Instead try something like that: