所以我讀過一些關於擴展Socket.IO的文章。出於各種原因,我不想使用內置的Socket.IO擴展機制(大多數情況下它效率低下,因爲它從我的角度出發,向Redis發佈了更多的東西)。Redis客戶端廣播問題(在Socket.IO中)
所以我想出了這個簡單的想法:
每個Socket.IO服務器創建的Redis的pub/sub /存儲的客戶端,連接到Redis的和訂閱的頻道。現在,當我想要廣播數據時,我只需將它發佈到Redis,然後所有其他Socket.IO服務器就可以獲得它並將其推送給用戶。
雖然有一個問題(我認爲這也是Socket.IO內置機制的問題)。假設我想知道所有連接用戶的數量。至少有兩種方式:
服務器A向Redis發佈
give_me_clients
。然後,每個Socket.IO服務器統計連接數併發布number_of_clients
。服務器A抓取這些數據,將其合併併發送給客戶端。每當用戶連接/斷開連接到服務器時,每個服務器都會在Redis中更新
number_of_clients_for::ID_HERE
。然後,服務器A僅提取數據並將其合併。可能會更有效率。
有這些解決方案雖然問題:
服務器A不知道其他的服務器。所以他不知道他應該什麼時候停止收聽
number_of_clients
。可以通過使服務器A知道其他服務器來解決它:只要服務器連接到Redis,他就會發布new_server
(服務器A獲取數據並將其存儲在內存中)。但是,當Redis - Socket.IO連接中斷時該怎麼辦? Redis有辦法通知客戶端某個客戶端已斷開連接嗎?其實和上面一樣。當Socket.IO服務器崩潰時如何清除
number_of_clients
數據?
所以真正的問題是:Redis可以通知(發佈到chanel)客戶端,其中一個連接剛剛結束?
我已經切換到ws,我基本上運行一個process.on退出並通過'wss.clients'循環並刪除我的redis存儲中的所有'user:ids'(如果服務器失敗)。我遇到的一個簡單問題是私人消息傳遞。如果我在端口9300和9301上有2個ws服務器,並且來自9301的用戶想要發送消息給9300中的用戶(或者可能是任何其他服務器/端口),我不知道如何讓其他用戶知道。我是否只將私人消息請求發佈到redis服務器,並找出用戶正在向其發送消息的wss服務器? –
@NiCkNewman我認爲,對於每個用戶,您應該瞭解該用戶在哪個服務器上(在像Redis這樣的共享位置)。然後,您只需檢索該信息並直接向目標服務器發送消息。但最有效的方法是通過用戶意識到他的朋友在哪個服務器上並直接將消息發送到該服務器。 – freakish
當然,所有這些都取決於上下文。例如,您可能想保留聊天記錄(例如Facebook),然後它變得更加複雜。我沒有太多的聊天服務器經驗,所以我不想把你引向錯誤的方向。 :( – freakish