Socket.IO - How to change timeout value option on client side?

16,670

The challenge here is that there are a bunch of different settings that interact with each other and some retry logic that all make a socket.io timeout not what you would normally expect. I should add that I am familiar with socket.io 1.0+, not 0.9 though this probably applies to both.

Lets review how a socket.io connection works.

  1. It attempts to make the initial connection.
  2. If that succeeds, then you're done with the connection.
  3. If that connection attempt does not return immediately, it will wait the timeout value that you pass in the initial options for a connection result.
  4. If your server is down, the connection attempt will likely fail quickly. This will result in a connect_error and if you register for that message on the socket with socket.on('connect_error', function() {...});, you will see that connect_error event.
  5. This connect_error is not a timeout. So, if the connection fails quickly (which it usually does when the server is just down), then you never get the regular timeout and the timeout argument you pass to io({timeout: 5000}) really doesn't come into effect. That only comes into effect when a connection to a server is just taking a long time (like an overly busy server or a server that accepted the TCP connection, but is really slow at responding). This is not usually what happens when a server is just down or unreachable.
  6. So, after socket.io gets a connect_error it marks this socket.io connection for retry.
  7. The delay before retrying is based on a whole bunch of things. Presumably, the reconnectionDelay option is part of the formula, but in looking at the code, there is also a backoff algorithm that lengthens the time between retries the more times it has retried. So, suffice it to say, there's some algorithm that calculates a given delay before retrying that varies for each retry.
  8. Then, after that calculated delay, it tries to connect again. This essentially repeats the process starting at step 1 again.
  9. As best I can tell, by default it keeps retrying forever. There is an option you can pass reconnectionAttempts that specifies the maximum number of reconnection attempts. This default to infinity if you don't pass it. But, if you pass 10, then it will give up after 10 successive connection failures.
  10. If you specify reconnectionAttempts, then after that many unsuccessful connection attempts, you will get a reconnect_failed event on the socket and it will give up.
  11. As best I can tell, there is no traditional timeout in the way that you are looking for where it would connect, attempt some retries, then give up after x amount of time. The timeout option applies only to a single reconnect attempt and not to the total amount of time it keeps trying to connect.

In a sample test page I've been experimenting with, I was able to implement my own traditional connection timeout like this:

var socket = io(...);

// set connect timer to 5 seconds
socket._connectTimer = setTimeout(function() {
    socket.close();
}, 5000);

socket.on('connect', function() {
    // socket connected successfully, clear the timer
    clearTimeout(socket._connectTimer);
});

This will wait a maximum of 5 seconds for a successful connection, regardless of how long a connection attempt takes or many reconnect attempts occur in that span of time. After 5 seconds without a successful connection, it shuts down the socket.

In my test app, I can see socket.io happily retrying the connection over and over again until after 5 seconds, my timer fires, I get notified of the "timeout" and I close the socket and it stops trying to retry any more.

Share:
16,670
Binh
Author by

Binh

Updated on July 13, 2022

Comments

  • Binh
    Binh almost 2 years

    I use Socket.IO 0.9.16 to establish a connection:

    io.connect(url)
    

    However, when the server dies, it takes 2 minutes timeout to detect error with the server.

    I already tried to reduce timeout to 5s by setting:

    io.connect(url, {'timeout': 5000, 'connect_timeout': 5000})
    

    But no success... How can I do this?

  • Binh
    Binh over 8 years
    I already checked it. it still can not change default timeout value
  • Binh
    Binh over 8 years
    Yes, thanks for your answer, jfriend00. I totally with your opinion. And now, I have another soluton for this issue is that: create timeout to check socket.socket.connected value.
  • jfriend00
    jfriend00 over 8 years
    @Binh - since it looks like you're new here on StackOverflow, are you aware that if you get your question answered, you can indicate that to the community by checking the green checkmark to the left of the answer. That will earn both you and the one who provided the answer some reputation points which can lead to more privileges on the site.