0

我正在編寫一個nodejs/socket.io應用程序,它在AWS Elasticache中使用集羣和Redis作爲RedisStore後端。該應用程序嚴重圍繞房間工作,我很難理解爲什麼只有Mobile Safari(iPad mini retina iOS7)發出請求後才能離開它訂閱的房間。即使關閉來自客戶端的連接,服務器上的套接字也會嗡嗡作響,並且房間的預訂完好無損,但其他瀏覽器可以不出問題地退出。NodeJS + Cluster + Socket.io + Redis - iOS在斷開連接後不會離開房間

  1. 的NodeJS v0.10.25
  2. Socket.io v0.9.16
  3. Redis的v2.8.6(AWS Elasticache)
  4. 的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吸收連接清理,但在l東部的房間訂閱都沒有了。然而,在我的平板電腦,退訂或斷開後,房間預訂保留在io.sockets.manager.roomClients對象:

Client: lhZsH1oL2vV7BML9QkSW { '': true, '/some-room': true } 

我是相當新的socket編程,所以我敢肯定,我失去了一些東西很明顯,但任何人都有與移動websockets類似的問題?

+0

偶爾也會發生這種情況。通常插座最終會斷開連接,但是幾分鐘後... 希望你找到答案! – lawx

+0

@lawm,謝謝!是的,當然,讓它靜坐幾分鐘後,客戶端隊列被清除。我現在可能會放棄它,但如果這項服務變得龐大,我想找到一種方法來強制刪除東西來釋放內存。我會發布任何更新 –

回答

0

所以我發現通過使用我自己的引用計數方法,我可以繞過需要socket.io來準確。由於我已經使用Redis通過pubsub支持套接字,所以我只是創建了另一個到redis的客戶端連接,並在到期時連接了socket.id。當我的套接字取消訂閱或斷開連接時,我刪除了與socket.id關聯的Redis中的所有關鍵字。通過這種方式,我可以立即獲得關於whos的快照,並且如果由於某種原因導致的關鍵字在disconnect/unsub上沒有被刪除,它將根據我爲setex調用設置的內容而過期。

我會盡量記住在兩天內回來標記我自己的答案是正確的。

+0

我知道這是舊的,但有機會分享您的代碼? – jdog