socket.ioがdisconnectしたらリロードする仕組みを入れてみた。

ひょんな事からリアルタイム付箋アプリケーションを紹介する機会があったので、紹介してたらいくつか不備が・・・。
やっぱり定期的に使って、エンハンス・修正しないとダメね。
ということで今日は修正してました。

自分のブラウザの使い方は割りと特殊な方かもしれないんだけど、一回タブを上げて用がなくなっても
開きっぱなしにしちゃうんですよ。おかげで↓みたいに沢山タブが出ている状況になる。

f:id:yosuke_furukawa:20120304022204p:image

そうすると、もう一度リアルタイム付箋アプリケーションにタブを戻した時にsocket.ioの接続が切れてて使えないという事がしばしば。その度に更新しているんだけど、結構面倒。

なので、socket.ioがdisconnectされた状態になっても再使用したら自動的にリロードする仕組みを導入してみたよ。
typestackに書いている方法(API Only - Stack Exchange)を参考にしてみました。

■Server側(Node.js)

app.get('/ping', function(req, res) {
    res.send('pong');
});

■Client側

var socket = io.connect();
var connected = false;

socket.on('connect', function (data) {
  connected = true;
});

socket.on('disconnect', function(data) {
  connected = false;
});

function reconnectSocket() {
  if (!connected) {
    $.get('/ping', function(data) {
      connected = true;
      window.location.href = unescape(window.location.pathname);
    });
  }
}

//なんかの操作
function someOperation() {
  reconnectSocket();
  ....
}

こうすることで、サーバーが生きている間は必ずリロードしに行ってくれます。
以下のような順序で実行されます。

0. disconnectになったらそれを受け取ってフラグをオフにする。
1. フラグがオフな状態でsomeOperation()等の操作を受け取ったら、reconnectを行う。
2. reconnect関数の中では、/pingパスにアクセス => 正常にデータが返ってくれば "生きている"とみなしています。
3. 生きていたら、 window.location.href に 自分のURLを入れてreload。

こんな感じになっています。
でもこの再接続方法が正しいのかなぁ。もう少しスマートな方法はないものかと思っていたら、普通にreconnectオプションがあった。

var socket = io.connect('http://localhost:3000/', {
  'reconnect': true,
  'reconnection delay': 500,
  'max reconnection attempts': 10
});

でもなんかうまく動かない。。。
A boolean indicating if we should try other transports when the connectTimeout occurs.
って書いてあるから、タイムアウトした時だけなのかな。
うーむ。。。
reconnectオプションについてはもう少し検証してみます。