jaraco / irc

Full-featured Python IRC library for Python.
MIT License
392 stars 87 forks source link

IRC Client - Ping Timeout Issue #16

Closed jaraco closed 8 years ago

jaraco commented 8 years ago

I am trying to use this library for IRC client things for a small IRC bot I'm writing. However, I've found that it always disconnects from a "Ping Timeout" and can't figure out why this is happening or how to prevent it from happening.

Library version: 8.0.1 Python version: 2.7.3 IRC Server: irc.quakenet.org:6667

I first tried incorporating the library in my own code based on the irccat.py example. However, I get the same issue with just running the irccat.py script, although I modified it to hard-code the third argument. It works perfectly until it's idle for 5-10 minutes at which point it disconnects from a ping timeout. I added a printout to the on_disconnect global handler and it's not called when the ping timeout occurs. I also tried adding a global handler for "ping", but that was never called either.

Let me know if there's anything I'm missing or if you need any more info. Thanks!


jaraco commented 8 years ago

I've seen other similar problems that may be related. I'll plan to test against the server as you reported. Thanks for the report.


Original comment by: Jason R. Coombs

jaraco commented 8 years ago

I think i may need more info on this issue. Or maybe I can help with the issue. By default, the irc object sets up a global responder for pings. If the 'ping' handler isn't being called, that probably means that the event loop isn't being activated properly.

One critical aspect of the event-driven style is that IRC.process_once must be called periodically. In this case, irccat and irccat2 are bad examples. They initially call process_forever (via start), which will repeatedly call process_once. However, in their on_welcome or on_join handlers, they enter a loop that runs until input is exhausted (and process_once will not be called again). Thus the ping responder will never be called, and if the connection is idle, the server will disconnect the client with a ping timeout.

Furthermore, I don't think on_disconnect will ever be called either, since there's nothing to handle the disconnect message.

It's possible your code is subject to this same issue. I believe testbot might have better behavior.

In any case, that's food for thought. I can still do some more testing and plan to in the future, but for now, that's one possible avenue you might consider.


Original comment by: Jason R. Coombs

jaraco commented 8 years ago

That is a good point, but I just tested it and am still experiencing the same issue. Here's the code I'm using: http://pastebin.com/u0y2z8zL

./irccat.py irc.quakenet.org:6667 MyUserName


Original comment by: Brian Gomberg

jaraco commented 8 years ago

Hi Brian. Using that code you pasted, I saved it as 'issue16.py' and then ran it as:

./issue16.py irc.quakenet.org jaraco

When I did, it appeared to connect and proceed as expected. Because it doesn't output any content, I used Wireshark to trace the connection, and I could see the client connect, set a nick, join the channel, and respond to PINGs with PONGs (every 180 sec). I let it run for more than 10 minutes without a problem (although the trace only shows the first 6.5 min).

This leads me to believe you may have an issue in your network environment that's causing your TCP connections to drop. I've witnessed for example ComCast dropping idle SSH connections after as little as 30 seconds.

If it is as I expect something in your network environment, you may need to add a PeriodicCommand to send a keepalive message of some kind. I'm not familiar enough with the protocol, but I'm guessing there's a client PING command or equivalent that could be configured as a PeriodicCommand.

When you run that script, what behavior do you get that's undesirable? Can you paste the offending output? Also, if possible, could you use tcpdump or WireShark to capture the packets when it fails, which might also shed some light on the situation?

If we can confirm it's an idle timeout issue, then we can probably put together a client-side ping for keepalive purposes. I remember another request for this feature in the past, so it's probably worth implementing in general.


Original comment by: Jason R. Coombs

jaraco commented 8 years ago

I've created #17 to look into a client-side ping for keepalive purposes.


Original comment by: Jason R. Coombs

jaraco commented 8 years ago

Unfortunately I can't easily run wireshark on this right now, but I was able to get this working.

The machine this is running on is one I connect to remotely and I also have a ZNC service running on it which I've been using to connect to IRC for a couple months now without issue. I tried setting up ZNC for this python program to connect to quakenet through ZNC, and everything seems to be working perfectly now. I'm not sure what method ZNC uses to avoid ping timeouts, but I've never seen it timeout.

I don't have any experience with using wireshark from the command line (just GUI in Windows), but I'll see if I can figure it out this weekend.


Original comment by: Brian Gomberg

jaraco commented 8 years ago

Sounds like you've found a solution. Good to hear. We'll continue to look into the ping timeout / keepalive support. Please comment or re-open if you find there are additional deficiencies that point to the implementation (especially if you can provide anything to help us reproduce the issue).


Original comment by: Jason R. Coombs

jaraco commented 8 years ago

I've been having ping timeout issues. I turned on debug and it looks like client doesn't receive a PING from the server so the client doesn't send a PONG. I don't think it's connection related because I also use irssi off the same box and my client stays connected fine.


Original comment by: Billy Vong

jaraco commented 8 years ago

Having the same issue. Suddenly messages will simply stop coming through, and 5 minutes later the client will time out. I've set up a log formatter that prints to STDOUT with a level of DEBUG and can't see anything useful around the time the messages stop coming in, which really is the most annoying bit. The issue only seems to happen after the script has been left running for quite some time, which hampers reproduction as well. My code is publicly available here: https://github.com/anlutro/ircbot


Original comment by: Andreas Lutro