question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Ping/Pong timeout problem

See original GitHub issue

The server sets the pingInterval & pingTimout, but engineio doesn’t use pingTimout for timeout. Instead it uses pingInterval for timeout.

https://github.com/miguelgrinberg/python-engineio/blob/master/engineio/client.py#L534-L544

image

self.ping_loog_event is on wait for self.ping_interval time, if the pong is not received for self.ping_interval time, ws is closed and while loop is exited.

Here is the log with timing to prove this.

pydev debugger: starting (pid: 57432)
23:14:10.55.779, client, INFO, WebSocket connection accepted with {'sid': 'B_k-Wy8NwJrpkfSaAAYD', 'upgrades': [], 'pingInterval': 2000, 'pingTimeout': 60000}		- pingInterval : 2 seconds, pingTimeout : 60 seconds
23:14:10.55.779, client, INFO, Engine.IO connection established
23:14:10.57.774, client, INFO, Sending packet PING data None
23:14:10.61.764, client, INFO, Received packet MESSAGE data 0


23:52:39.613.351, client, INFO, Sending packet PING data None
23:52:39.830.123, client, INFO, Received packet PONG data None
23:52:41.614.032, client, INFO, Sending packet PING data None
23:52:41.830.636, client, INFO, Received packet PONG data None
23:52:43.614.457, client, INFO, Sending packet PING data None
23:52:43.832.420, client, INFO, Received packet PONG data None
23:52:45.615.007, client, INFO, Sending packet PING data None
23:52:45.831.851, client, INFO, Received packet PONG data None
23:52:47.615.802, client, INFO, Sending packet PING data None
23:52:47.918.927, client, INFO, Received packet PONG data None
23:52:49.616.014, client, INFO, Sending packet PING data None
23:52:49.833.062, client, INFO, Received packet PONG data None
23:52:51.616.422, client, INFO, Sending packet PING data None					- last ping sent
23:52:53.617.275, client, INFO, PONG response has not been received, aborting	- after 2 second (pingInterval) PONG response has not been received, its aborting. This should happen after 60 seconds (pingTimeout).
23:52:53.617.275, client, INFO, Exiting ping task
23:52:53.618.242, client, INFO, Exiting write loop task
23:52:53.619.240, client, INFO, Unexpected error "[WinError 10004] A blocking operation was interrupted by a call to WSACancelBlockingCall", aborting
23:52:53.620.236, client, INFO, Waiting for write loop task to end
23:52:53.620.236, client, INFO, Waiting for ping loop task to end
23:52:53.621.235, client, INFO, Engine.IO connection dropped

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:14 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
miguelgrinbergcommented, Jul 21, 2020

Let me start with this. If you found that by changing this project in certain way you get a better result, then by all means, use your modified version of the package. It’s perfectly fine to do that, you would not be the only one.

What we are discussing here is a change that will apply to every user of this project, not your particular case. I hope we are clear on this.

Whatever it may be “pingInterval > pingTimeout” or “pingTimeout > pingInterval”, the client should use pingTimout for timeout not pingInterval for timeout.

You are telling me that you think it is okay for several ping packets to go unanswered if the ping timeout is much longer than the ping interval. I disagree. I do not believe this is a correct approach. Every ping must be responded with a pong, and until the pong arrives the client should not send another ping.

Yes I read it. This line uses pingTimout to reset, not pingInterval. But engineio uses pingInterval to timeout.

My point is that this JS code is designed to work only when pingTimeout < pingInterval. When you have the reverse, the pingTimeout will never trigger, so their implementation is buggy and does not do what you want this project to do.

As I said I have no control over the server.

You seem to be in a bad situation with this server you are connecting to. The (2s, 60s) timeouts that were configured in this server make absolutely no sense. But that is not what we are discussing here.

How about this? In the read_loop() function and write_loop(), you’ve used a max of timeouts

Those are not disconnection timeouts. The purpose of the max() there is to make sure that we wait long enough on the requests to let any other timeouts kick in first. I could do 2 times the max and it would still work.

But if you agree on the fact that we should use only pingTimout for timeout and not pingInterval

I can agree with this statement at a high-level, and this is certainly correct when pingTimeout < pingInterval, but I don’t agree to let ping packets go unanswered, so I don’t see how we can make this work. Sorry.

0reactions
miguelgrinbergcommented, Jul 22, 2020

The defaults in the Node server are (25, 5). They used to be (25, 60) a few years ago.

If the server is telling the client to send ping in every 60 seconds, why would the server timeout in 5 seconds itself?

The server is telling the client to send a ping every 25 seconds. The expected time for the pong to be sent back by the server is 5 seconds or less.

Long ago, when the timeout was 60 seconds, the server used it instead of the ping interval. I copied this behavior several years ago. Since then, the node server realized that the (25, 60) numbers didn’t make a lot of sense, and switched to (25, 5). I have not made the switch yet but plan to. When I make this change, the timeout used by the server to kill clients is going to be either pingInterval or max(pingInterval, pingTimeout), I haven’t decided which is better yet.

If the pingTimeout is to be used by server itself, why would it send to client?

The pingTimeout is provided to clients with the intention that they will use it, but it needs to be less than pingInterval to be useful. You saw in the JS client that a timeout that is larger than the interval effectively deactivates any timeouts on the client side.

It was my choice in the Python client to ignore pingTimeout and give the server extra time to respond, up to pingInterval seconds, regardless of how pingTimeout is set. As I said before, a longer pingTimeout makes no sense because you would have pings w/o a matching pong, and a shorter pingTimeout can be safely extended all the way to pingInterval without affecting anything, and this sometimes helps prevent disconnections in unreliable networks such as mobile.

Read more comments on GitHub >

github_iconTop Results From Across the Web

FastAPI websocket ping/pong timeout - Stack Overflow
the ping pong happens in uvicorn, and there's no current way to configure those values, there's an open issue here : github.com/encode/uvicorn/ ...
Read more >
Timeout Rule - PingSkills
If the person calling the time-out is ready before the one minute is up the time-out is complete. So the person calling the...
Read more >
WebSocketTimeoutException: ping/pong timed out error
I use Binance python, after times this error occures. 2021-06-15 22:27:18993 - ERROR - ping/pong timed out Traceback (most recent call ...
Read more >
The Mental Timeout | Samson Dubina Table Tennis Academy
In table tennis, each player has one timeout per match lasting up to 60 seconds. ... However, many players don't use their mental...
Read more >
Timeouts - websockets 10.4 documentation
To avoid these problems, websockets runs a keepalive and heartbeat mechanism based on WebSocket Ping and Pong frames, which are designed for this...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found