2013-07-02 124 views
6

Socket.io API有能力發送消息到所有客戶端。socket.io如何通過多個服務器發送消息?

使用一個服務器和內存中的所有套接字,我理解該服務器可以如何向其所有客戶端發送消息,這很明顯。但是使用Redis來存儲套接字的多臺服務器呢?

如果我有客戶端一個連接到連接到服務器的服務器ÿ和客戶端bŽ(和用於存儲一個Redis的框)和I做socket.broadcast.emit一個服務器上,則客戶機上的其他服務器將收到此消息。怎麼樣?

的客戶端如何實際連接到其他服務器獲取該消息?

  • 是一個服務器告訴其他服務器將消息發送到其連接的客戶端?
  • 服務器是否建立自己的連接到客戶端發送該消息?

回答

7

Socket.io使用MemoryStore的默認,因此所有連接的客戶端將被存儲在內存中,根本不可能(當然,不是安靜,但後來更多)發送和從連接到不同的插座客戶接收事件.io服務器。

讓所有socket.io服務器接收所有事件的一種方法是所有服務器都使用redis的pub-sub。因此,使用socket.emit可以發佈到redis。

redis_client = require('redis').createClient(); 
redis_client.publish('channelName', data); 

和所有的插槽服務器通過Redis的以及在接收到消息其發射到連接到他們的客戶端訂閱該頻道。

redis_sub = require('redis').createClient(); 
redis_sub.subscribe('channelName', 'moreChannels'); 

redis_sub.on("message", function (channel, message) {   
    socket.emit(channel, message); 
}); 

複雜的東西!但等等,結果你實際上並不需要這種代碼來實現目標。插座。io擁有RedisStore,它基本上做了上面的代碼應該以更好的方式做的事情,以便您可以編寫Socket.io代碼,就像您爲單個服務器編寫代碼一樣,並且仍然會通過redis傳播到其他socket.io服務器。

總結socket.io通過使用redis作爲通道而不是內存來跨多個服務器發送消息。

+0

完美,正是我所期待的! – hackerhasid

1

有幾種方法可以做到這一點。更多信息in this question。關於Redis中的pub/sub如何工作的一個很好的解釋是here, in Redis' docs。該範式如何工作的解釋一般是here, on Wikipedia

報價Redis的文檔:

訂閱,取消訂閱和發佈實施,其中(引用維基百科)發送者(發佈者)的 不編程到它們的消息發送到特定接收 發佈/訂閱 消息傳遞模式(用戶)。相反,發佈的消息被描述爲 頻道,而不知道可能有哪些用戶(如果有的話)。 訂閱者表示對一個或多個頻道感興趣,並且只接收到 感興趣的消息,而不知道哪些(如果有) 發佈者。發佈者和訂戶 的這種解耦可以允許更大的可伸縮性和更動態的網絡拓撲。

+1

花了我一些時間來解釋這是如何回答我的問題,但重新閱讀這些信息後,我意識到幕後發生的事情是,socket.io使用redis pubsub發佈和分發其他服務器客戶端的消息和它自己的 – hackerhasid

相關問題