2017-02-17 77 views
0

我正在爲基於回合的Unity遊戲編寫node.js websocket後端。這是我第一次使用node.js和websockets,所以我想我會讓玩家可以重新連接,並且會得到他們錯過的任何消息。Websockets - 自定義排隊系統是否有意義?

然後,我開始在遊戲中實現它,並想測試我的排隊系統,所以我關掉我的互聯網連接,並把它背在 - ,驚訝地發現連接躲過了這場,任何錯過的消息是通過相同的連接發送。無需重新連接並將積壓發送到新連接。

因此,似乎websocket技術已經處理離線排隊?通過自己做這些事情來使服務器代碼複雜化(並通過將消息保留在那裏來增加服務器的內存負載)是否有意義?

另外,它怎麼能保持套接字連接沒有互聯網連接活着?是否有一個標準化的超時時間,或雙方都會跟蹤它,除非我手動關閉它?

謝謝!

+0

據我所知,你使用socket.io的權利? –

+0

不,我選擇直接使用websockets(即require('websocket')。server),因爲我不需要socket.io具有的ajax回退。 – SvenM

+0

我在半年前閱讀並記錄**保證消息傳遞確認已被證明是不可能的,但TCP保證在給定「無限」重試的情況下執行傳送和訂單。** 您可以嘗試使用Wireshark或類似工具來跟蹤套接字並執行一些測試以瞭解現在的隊列如何適用於WebSockets。 –

回答

2

然後,我開始在遊戲中實現它,並想測試我的排隊系統,所以我關掉我的互聯網連接,並把它背在 - ,驚訝地發現連接躲過了這場,任何錯過消息通過相同的連接發送。無需重新連接並將積壓發送到新連接。

關閉連接不會自動殺人建立了這方面的任何插座。當他們嘗試發送數據失敗時,套接字最終會關閉,經過多次重試和時間流逝後,他們所得到的都是錯誤。如果一個套接字沒有主動嘗試發送任何數據,並且沒有任何配置的keep-alive可以自動完成,那麼它可能會在一個死連接中呆上幾個小時,並且根本不知道連接已經死了。只要套接字沒有被使用,就沒有自動的方式,它甚至不知道它是端到端連接不再起作用。它只是在它試圖使用連接並且得到一個錯誤時纔會發現。

請注意,如果服務器進程崩潰,但連接保持活動狀態,則情況會有所不同。在這種情況下,服務器上的TCP堆棧會看到服務器進程崩潰,並嘗試清理它正在使用的任何套接字,並將關閉數據包發送到另一端,另一端將主動告知該套接字是關閉。但是,僅僅打亂交通工具的情況並不一樣。

所以它看起來像websocket技術已經處理離線排隊?通過自己做這些事情來使服務器代碼複雜化(並通過將消息保留在那裏來增加服務器的內存負載)是否有意義?

websocket是TCP套接字上的協議層。 TCP是一種可靠的傳輸方式,這意味着當它發送數據時遇到困難(但沒有收到任何關於套接字已被另一端關閉的通知),它會掛起並重試數據。它最終會放棄並回傳一些錯誤。

您可能會對socket.io感興趣,它是webSocket頂層的一個圖層。它增加了一些與此處相關的東西:

  1. 定期ping從端到端,以便它知道傳輸何時中斷。
  2. 當插座關閉或運輸中斷時無縫自動重新連接。
  3. 在連接暫時中斷時自動排隊發送的數據。

另外,它怎麼能保持套接字連接沒有互聯網連接活着?是否有一個標準化的超時時間,或雙方都會跟蹤它,除非我手動關閉它?

正如我剛纔所說,如果沒有端嘗試發送數據和互聯網連接在兩個端點之間的中間某處中斷,則可能的WebSocket根本不知道連接當前不起作用。定期知道連接是否有效的唯一方法是通過連接發送數據並查看是否得到及時響應。這是socket.io用它的ping/pong消息所做的。

無論物理連接發生什麼,保持邏輯連接的方式都是在物理連接之上使用額外的層(如socket.io在webSocket之上)。這樣可以讓您擁有可能重新啓動物理連接而無需更改邏輯連接的代碼。這正是socket.io從客戶端所做的事情。如果您希望從服務器端獲得類似的東西,您可能需要實現自己想要發送給客戶端的數據隊列,並且只有在確定它們已成功發送時才從隊列中刪除。