Offline capable app: reconnection when online?

346 views
Skip to first unread message

Felix E. Klee

unread,
Oct 21, 2012, 6:26:01 PM10/21/12
to sock...@googlegroups.com
I am developing a game with offline capability (e.g. for mobile
devices). Communication is via Socket.IO, with [localStorage][1] as
offline cache for hiscores. Details (client = browser):

* On client load:

- hiscores are retrieved from localStorage,

- updated hiscores are requested from the server,

- unsaved hiscores are sent to server (for saving in database).

* On new hiscores on server: new saved hiscores are broadcasted to all
clients

* On new hiscore entry on client: unsaved hiscores are sent to server

This mostly works fine, for example in the following scenario:

1. Load game.

2. Stop server, for testing.

3. Play game, and submit new hiscores entry.

4. Some time later: start server

In step 4, the hiscores entry gets automatically sent to the server *if*
the server hasn't been offline for too long. At the moment I am using
default Socket.IO settings: Socket.IO tries reconnecting ten times over
a short period of time.

Now, how do I configure Socket.IO so that step 4 always works? Should I
just tell it to try reconnecting forever? What is the recommended way to
handle situations like this?

By the way, the app uses [application cache][2].

[1]: http://www.w3.org/TR/webstorage/#the-localstorage-attribute
[2]: http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#appcache

Felix E. Klee

unread,
Oct 22, 2012, 5:02:28 AM10/22/12
to sock...@googlegroups.com
My own solution proposal:

1. Set "max reconnection attempts" to "infinity".

2. Check [`navigator.offline`][1] and `navigator.online`, and listen to
the corresponding `online` and `offline` events. Take action on
browser state changes:

+ Turned offline: Call Socket.IO's `disconnect`.

+ Turned online:

- Not connected to Socket.IO (`socket.connected` is false):
Call Socket.IO's `connect`, then (re-)send hiscores to server.

- Still connected: Do nothing, just wait (but see below for
possible issues).

Does that look like a robust solution?

Does setting the reconnection attempts to "infinity" really make sense?

The problem I see is that according to documentation an "exponential
back off algorithm" is used, making delays between retries longer and
longer. So, when the user goes back online it may take, say, an hour
until Socket.IO attempts to reconnect. Is it possible to turn off the
"exponential back off algorithm"?

[1]: http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#browser-state

Arnout Kazemier

unread,
Oct 22, 2012, 12:00:52 PM10/22/12
to sock...@googlegroups.com
No, setting the reconnect to infinity does not make sense as you cannot turn of exponential back off
(it's there for a reason) But then again, you can just disable reconnect and handle it your self. The only
thing that reconnect is doing is handling disconnect events.

Felix E. Klee

unread,
Oct 22, 2012, 6:56:09 PM10/22/12
to sock...@googlegroups.com
Hah! Just discovered `socket.socket.reconnect()`.

So this should work and preserve queued events:

window.setTimeout(function () {
if (!socket.connected && !socket.connecting) {
socket.socket.reconnect();
}
}, 5000);

Makes sense?

(aside from the general issue that repeated connection attempts may
stress the server / connection if it is overloaded)

Basic test (from Chrome developer console):

1. `socket = io.connect('http://localhost:3001', {reconnect: false});`

2. server down

3. `socket.emit('event', 1);`

4. server up

5. `socket.socket.reconnect();`

Works!

Felix E. Klee

unread,
Oct 22, 2012, 5:06:49 PM10/22/12
to sock...@googlegroups.com
On Mon, Oct 22, 2012 at 6:00 PM, Arnout Kazemier <in...@3rd-eden.com>
wrote:
> No, setting the reconnect to infinity does not make sense as you
> cannot turn of exponential back off (it's there for a reason)

Thanks for clarification! I found further information in a related
GitHub issue:

<https://github.com/LearnBoost/socket.io-client/issues/226>

> But then again, you can just disable reconnect and handle it your
> self.

But how?

There is no `reconnect` method on the `socket` object. So I cannot do
something like:

window.setTimeout(function () {
if (!socket.connected && !socket.connecting) {
socket.reconnect();
}
}, 5000);

I could do it as follows, but then I will lose all queued events:

window.setTimeout(function () {
if (!socket.connected && !socket.connecting) {
socket = io.connect(host);
}
}, 5000);

The only working solution I see would be the ugly hack mentioned as
comment to the aforementioned GitHub issue:

<url:https://github.com/LearnBoost/socket.io-client/issues/226#
issuecomment-2954300>

Felix E. Klee

unread,
Nov 6, 2012, 4:49:37 AM11/6/12
to sock...@googlegroups.com
>> No, setting the reconnect to infinity does not make sense as you
>> cannot turn of exponential back off (it's there for a reason)
>
> I don't think this is true anymore, there's a "reconnection limit"
> option that caps the exponential backoff.

Thanks for pointing that out. Excerpt from [lib/socket.js][1]:

if (self.reconnectionDelay < limit) {
self.reconnectionDelay *= 2; // exponential back off
}

I just saw your message today, i.e. after posting my message "Offline
capable app: reconnection when online?". I may go back to automatic
reconnect then, with:

'max reconnection attempts': Infinity
'reconnection limit': 20000 // 20 seconds

[1]: https://github.com/LearnBoost/socket.io-client/blob/master/lib/socket.js
Reply all
Reply to author
Forward
0 new messages