2013-06-03 101 views
2

我有一個獨立的Node.js應用程序,它具有偵聽特定端口的SocketIO服務器,例如, 8888.現在我正嘗試在羣集中運行此應用程序,並且由於羣集隨機分配工作人員請求,因此一旦握手並獲得一名工作人員的授權,XHR輪詢模式下的SocketIO客戶端就會被路由到另一名工作人員,而他們沒有握手並且混亂開始。Node.js集羣上的SocketIO

而且由於員工不分享任何內容,所以找不到解決方法。這個問題有沒有已知的解決方案?

+0

你真的需要socket.io和請求輪詢嗎?你可以使用ws。 –

+0

在我們的案例中,socketio客戶端可能位於沒有可靠HTTP連接的設備上,例如http://teradek.com/pages/bond,所以ws不會總是工作 - xhr-polling更可靠 –

+0

這仍然是一個未解決的問題,socket.io https://github.com/LearnBoost/socket。 io/issues/952 他提示給http-upgrade部分添加超時以緩解它 –

回答

1

沒有「簡單」的解決方案。你所要做的是:

  • 如果一個客戶端連接到一個工人,與工人-ID和潛在的額外識別-ID一起保存連接-ID在全球(=所有員工都可以訪問)商店(即redis)。
  • 如果客戶端被路由到另一個工作人員,請使用該商店查找哪個工作人員負責此客戶端(使用連接標識或附加的標識ID,然後將其交給該工作人員(與在的NodeJS工人 - 碩士 - 工人溝通,或通過Redis的-PUB-SUB)

我HABE實現這樣的事情與sock.js和複雜性的額外程度:我有四名工人2個的node.js服務器每一個,所以我不得不使用redis-pub-sub進行工/工交流,因爲不能保證它們在同一臺機器上。

+0

謝謝,@heinob。你是否必須破解sock.io的來源才能做到這一點? –

+1

正如我所說的,我是用sock.js做的,因爲它似乎比io更穩定。但我沒有破解消息來源。普通標準。 – heinob

+0

它握手,但據我所知,它不能找到運輸。基本上,我必須切換到使用websockets協議而不是XHR輪詢(在這種情況下,它將連接到不同的Node工作人員,因此必須重新連接),並使用Redis pub-sub調度程序來處理事件。但理想情況下,我希望Socket.io只是爲我工作。我必須嘗試更多。 –

1

其實 a 簡單解決方案:使用Redis來存儲套接字狀態。
一切都在Socket.IO documentation說明:

默認 '會話' 存儲在Socket.IO是在存儲器(MemoryStore)。

MemoryStore只允許你在一個單一 過程部署socket.io。如果您想將擴展爲多個進程和/或多個 服務器,則可以使用我們的RedisStore,它使用Redis NoSQL數據庫 作爲中間的人。

所以爲了給例如改變RedisStore我們補充一點:

var RedisStore = require('socket.io/lib/stores/redis') 
    , redis = require('socket.io/node_modules/redis') 
    , pub = redis.createClient() 
    , sub = redis.createClient() 
    , client = redis.createClient(); 

// Needs to be done after 'listen()' 
io.set('store', new RedisStore({ 
    redisPub : pub 
, redisSub : sub 
, redisClient : client 
})); 

當然,你需要有一個Redis的服務器運行。

+0

我知道這件事,但它不起作用。 –

+0

它在開發和產品中都適合我。你有什麼問題?仍然沒有握手? – maxdec