iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

今日目標,介紹 WebSocket 技術、解釋之後如何使用 WebSocket 實作遊戲機制。

WebSocket

WebSocket 是一種基於 TCP 的全雙工網路傳輸協定。早期的推播技術、訊息即時更新技術,都是使用 輪詢(polling)[1] 的方式,但這種作法會需要大量的請求和回覆,造成同樣的標頭(header) 重複使用,而且用的是很肥的 HTTP 標頭,實際傳輸的內容大小可能比標頭還小,因此這種作法會佔據大量傳輸資源(尤其是需要短時間不斷更新的功能),於是 WebScocket 技術就誕生了。
在 WebSocket 技術中,Server 和 Client 之間會先透過 HTTP 協定 握手(handshake)[2] 建立一個 TCP 通道(類似從 server 拉水管到 client),之後傳輸訊息就可以直接透過通道,而不必再使用 HTTP 協定的標頭,而且他是全雙工,所以 Server 可以主動向 Client 傳輸資料。
WebSocket 使用的具體過程為,Client 先和 Server 發起連線,當成功連線後 Client 可以訂閱(subscribe) 代理(broker)[3],當 Server 發送訊息到代理時,有該代理會將訊息傳給有訂閱的 Client。在建立連線時,Client 會有特定的 Session 被 Server 儲存,所以 Server 能透過這些 Session 來確定各個連接的 Client 是誰,也就能做到指定對象的傳輸。

遊戲機制

先列出功能需求:

  • 顯示房間列表:顯示目前有哪些房間、各房間內有多少人,並且即時更新
  • 加入、退出房間:玩家能夠自由進出房間
  • 傳遞個別房間的資訊:當玩家進入或退出房間時,其他玩家能夠即時的看到,以及玩家會有「準備」的機制,大家都準備好,房主才能開始遊戲
  • 傳遞個別房間的遊戲狀態:遊玩過程中,不斷更新目前的出牌玩家出的牌、每個人當下的手牌數、每個人自己的手牌
  • 結算遊戲:當有人結束,要發送訊息給所有人,通知遊戲結束,並且顯示贏家,也可以看到其他人剩餘的牌

功能需求的實現

  • 顯示房間列表:
    • 使用 WebSocket,因為資訊會不斷更新
    • 讓每個 Client 都先訂閱一個代理,當任何房間資訊有改變(新增或減少房間、各房間的人數變化),由 Server 發送最新的狀態到指定代理,每當 Client 接收到訊息就更新頁面
  • 加入、退出房間:
    • 透過 API 來實現,因為加入或退出的動作不會一直重複發送請求
    • 撰寫相關的 API 來完成
  • 傳遞個別房間的資訊:
    • 使用 WebSocket,因為房間會不斷有人進出和準備
    • 由 Server 發送訊息給指定房間的每個 Client,以此方式做到「群播(multicast)」的功能,當 Client 接收到訊息就更新頁面
  • 傳遞個別房間的遊戲狀態:
    • 使用 WebSocket,因為遊戲狀態會需要不斷傳送資料
    • 由 Server 發送手牌資訊給個別 Client(手牌資訊應該要只有自己看的到);由 Server 透過群播發送其他人的資訊
  • 結算遊戲:
    • 使用 WebSocket,因為結束遊戲需要即時性和統一性
    • 由 Server 透過群播發送結束訊息,並顯示贏家和其他人剩餘的手牌

名詞解釋

  • [1] 輪詢(polling):指的是 server 每隔一段時間就來詢問「你有要傳訊息嗎?」,有的話就處理,沒有的話就不管它。
  • [2] 握手(handshake):全稱為「三方交握(three-way handshake)」,是指建立 TCP 連線的過程,它的目的是用來確認雙方都要建立連線。發起端會先問:「我要跟你連線,你 ok 嗎?」,對方會回應「好啊沒問題,那你準備好了嗎?」,發起端再回應「我準備好了,我要傳囉」。到這邊就是建立好連線,之後就可以開始傳送訊息。
  • [3] 代理(broker):訊息的中介平台,負責在 Server 和 Client 中間傳輸訊息。

參考資料


今天先描述我們之後要開發的功能,並稍微解說之後如何實現這些功能,難免有點枯燥,但總要了解基礎嘛~ /images/emoticon/emoticon06.gif


上一篇
Day 13 - 頁面模板 Thymeleaf Page Layout
下一篇
Day 15 - WebSocket Config
系列文
Spring Boot... 深不可測31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言