2014-03-03 21 views
3

我正嘗試在Clojure中構建可伸縮的聊天服務器。我使用http-kit,compojure和redis pub/sub在不同節點之間進行通信(扇出方法)。服務器將使用websocket連接b/w客戶端服務器,並使用後退到長輪詢。一個用戶可以有多個連接來與瀏覽器中的每個選項卡的一個連接進行聊天,並將消息傳遞給所有連接。Clojure中的可擴展聊天服務器。 B/w重新連接存在和消息到達問題

當用戶連接我與隨機UUID存儲在一個原子上的信道作爲

{:userid1 [{:socketuuid "random uuid#1 for uerid1" :socket "channel#1 for userid1"} 
      {:socketuuid "random uuid#2" :socket "channel#2"}] 
:userid2 [{:socketuuid "random uuid#1 for userid2" :socket "channel#1 for userid2}]} 

該消息被髮布到兩者的WebSockets和長輪詢通道的公共路由因此,基本上,該消息結構看起來像

{:from "userid1" :to "userid2" :message "message content"} 

服務器發現在原子的所有信道爲:從和:將用戶ID和消息發送到爲各個用戶所連接的信道,還它出版超過其中連接Redis的服務器的消息節點尋找通道存儲在他們自己的原子中並將消息傳遞給相應的用戶。

所以我遇到的問題是,如何正確實施存在。基本上,當一個通道斷開狀態可以是「服務器關閉」或「客戶端關閉」時,http-kit會向你發送一個狀態,而我可以處理服務器斷開連接(客戶端將自動重新連接),但當斷開連接時發生在客戶端,例如。用戶導航到另一個頁面並在幾秒鐘後連接。 如何確定用戶在客戶端斷開連接時已脫機。另外,我擔心在長輪詢模式(我的長輪詢超時時間爲30秒)時,黑/白重新連接。

也請爲上述架構提出一個良好的存在機制。謝謝。

如果您需要更多信息,請發表評論。由於

編輯#1:

你能推薦上聊天服務器實現存在一個很好的教程/材料,我似乎無法找到它的任何東西。

我目前的解決方案 - >我目前正在維護一個特定用戶ID的連接通道的全局計數和最後連接的時間戳,並且當用戶斷開計數時減少,並且實現超時10秒,如果用戶已經重新連接(即最後一次連接的郵票是10秒鐘,計數仍然爲零),如果不是,那麼用戶會說已離線,您會推薦此解決方案嗎?如果不是原因,或者任何改進或更好方法表示讚賞。 另請注意我正在使用http-kit中的計時器/計劃任務,這些超時性能效果會不會顯着?

+0

我無法真正對性能或最佳實踐發表評論,我所做的只是像剛剛描述的那樣實施。不過,我剛剛閱讀了該公告:https://groups.google.com/forum/#!topic/clojure/5J4L8pbGwGU對於我來說,這可能對您有用。也許它對於長輪詢和websocket連接都有一個通用的「客戶端斷開連接」方法。 – sveri

回答

3

客戶端有兩種不同的情況。

  1. 長輪詢。我不明白這是一個問題,如果客戶端窗口關閉,那麼不會再無法輪詢。一個客戶少要求數據。
  2. Websockets。在協議中有一個密切的方法可用。如果您正確實施,客戶端應發送通知。例如,請參閱:Closing WebSocket correctly (HTML5, Javascript)

這是否回答你的問題?

+0

感謝您的回覆。是的,你的回答簡化了事情請參閱編輯後的問題以瞭解後續問題。謝謝。 –