AWS Elasticache のクラスターと Redis を RedisStore バックエンドとして使用する nodejs/socket.io アプリケーションを作成しています。アプリは部屋の周りで重く動作します.Mobile Safari(iPad mini retina iOS7)だけが、サブスクライブしている部屋から退出するリクエストを送信した後、退出できない理由を理解するのに非常に苦労しています. クライアント側からの接続を閉じても、ソケットはサーバー上でハミングしたままになり、ルームへのサブスクリプションはそのまま残りますが、他のブラウザーは問題なく終了できます。
- NodeJS v0.10.25
- Socket.io v0.9.16
- Redis v2.8.6 (AWS エラスティックキャッシュ)
- Ubuntu 14.04 LTS (TCP モードのロードバランサーの背後にある EC2)
さて、私のコードでは、io.sockets.manager.roomClients
オブジェクトを使用して反復処理を行い、実際に使用されている部屋を確認しています。これはio.sockets.clients()
、一定期間接続を開いたり閉じたりすると、レポートが完全に不正確なデータになるためです。
私のコードはここに置くには長すぎて、かなりプライベートですが、基本的に私が持っているものは次のとおりです。
サーバ:
if (cluster.isMaster) {
function heartbeat(){
// io.sockets.clients() doesn't splice dropped connections off the array
// so we have to use io.sockets.manager.roomClients to see active rooms
for( var i in io.sockets.manager.roomClients ) {
console.log("Client:", i, io.sockets.manager.roomClients[i] );
}
setTimeout(heartbeat,5000);
}
heartbeat();
} else {
io.sockets.on('connection', function (socket) {
socket.on('subscribe', function (room) {
console.log("Starting:",room);
socket.join(room);
});
socket.on('unsubscribe', function (room) {
console.log("Leaving:",room);
socket.leave(room);
});
socket.on('disconnect', function () {
console.log("Close Shop");
});
});
}
クライアント:
socket.emit('subscribe', 'some-room');
サーバーログ
Starting: some-room
そして、Client
各タイムアウトティックでログを取得します:
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
さて、本題です。デスクトップ ブラウザの登録を解除または切断した場合:
socket.emit('unsubscribe', 'some-room');
Leaving: some-room
または
socket.disconnect();
Close Shop
目盛りは次のようになります。
Client: lhZsH1oL2vV7BML9QkSW { '': true }
私たちが知っているように、socket.io は接続のクリーンアップを苦手としていますが、少なくともルームのサブスクリプションはなくなっているためです。ただし、私のタブレットでは、購読を解除または切断した後、部屋の購読はio.sockets.manager.roomClients
オブジェクトに残ります。
Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true }
私はソケットプログラミングにかなり慣れていないので、明らかな何かが欠けていると確信していますが、モバイル Websocket で同様の問題が発生した人はいますか?