NowJS and Reconnects 保留
原文http://blog.nowjs.com/
This particular feature has been highly anticipated by the NowJS community for some time. With the switch to Socket.IO 0.6.18, which now has built-in support for socket reconnecting, implementation of this feature was actually quite doable. We've tested with both simulated server downtime and client network issues, and it's worked satisfactorily. Several minor changes were necessary to support this feature in Now -- nothing that actually affects the API for developers using this tool; just a few changes to how things work in the backend.
Several disclaimers to make about Now and the general state of reconnects: first of all, it's not possible to preserve the client's session ID without forking Socket.IO. I have it from one of the Socket.IO folks that 0.7 will make everything public, including generateSessionId(), so when we bridge over to that version (we'll have to make sure that nothing breaks -- we've been developing a test suite, so that should hopefully ease the transition), this may change.
Additionally, client groups are not preserved across reconnects. One way to handle this would be to have the client know which groups he's in, and then send this information when the socket's reconnect event is triggered.
Note that client scopes, however, are preserved, so in the multiroom chat example, for instance, a reconnecting user originally in room 3 will be treated as if he's in room 1, but he'll still have the same name.
And now, the code.
The first block of code, pulled from handleDisconnection(), is as follows:
// y-combinator trick
(function (y) {
y(now, y, [now]);
})(function (obj, fn, seen) {
for (var i in obj) {
if (obj[i] && seen.indexOf(obj[i]) === -1 &&
typeof obj[i] === 'object' && obj[i] != document) {
seen[seen.length] = obj[i];
fn(obj[i], fn, seen);
}
else if (typeof obj[i] === 'function' && obj[i].remote) {
delete obj[i];
}
}
});
I've omitted the tiny portion from constructRemoteFunction() where I tagged all remote functions as such. Essentially, this snippet runs through the now object and deletes all remote functions -- if this is not done, then upon reconnecting, the user will find himself running into infinite recursion -- when re-establishing the connection, since the client transmits his scope first, the server-side function will be redefined to call the client-side function, which simply calls the server-side function.
About the actual code: I figured it would be amusing to use the y-combinator trick instead of conventional methods which involve binding values to variables, especially since Flotype (the company behind NowJS) is a YC-funded company. Plus, it's just an awesome concept.
The other snippet, pulled from handleNewConnection(), is both straightforward and standard:
if (client.handled) return;
client.handled = true;
Since the rest of the function involves attaching function listeners, this ensures that these listeners are only attached once.
Well, that's that. Let us know what you think in the comments below, and in our IRC channel #nowjs on irc.freenode.net