文章目錄
- 項目背景
- 核心技術
- 創建項目
- WebSocket
- 消息推送
- 輪詢操作
- 報文格式
- 握手過程(建立連接過程)
項目背景
- 用戶模塊
- 用戶的注冊和登錄
- 管理用戶的天梯分數,比賽場數,獲勝場數等信息
- 匹配模塊
- 依據用戶的天梯積分,來實現匹配機制
- 對戰模塊
- 把兩個匹配到的玩家,放到一個游戲房間中,雙方通過網頁的形式來進行對戰比賽
核心技術
- Java
- Spring/Spring Boot/Spring MVC
- HTML/CSS/JS/AJAX
- MySQL/MyBatis
- WebSocket
創建項目
相關依賴
WebSocket
消息推送
我們之前學習的服務器開發,主要是這樣的模型:
- 客戶端主動向服務器發起請求,服務器收到之后,返回一個響應
- 如果客戶端不主動發起請求,服務器是不能主動聯系客戶端的
我們是否需要,服務器主動給客戶端發送消息這樣的場景呢?
- 需要。——消息推送
- 當玩家 1 在棋盤上落子的時候,玩家 1 的客戶端就需要給服務器發一個消息,告訴服務器這個玩家把棋子落在哪個位置了
- 玩家 2 也就需要及時地獲取到玩家 1 的落子信息
- qq、微信、五子棋…
輪詢操作
當前已有的知識,主要是 HTTP
。但 HTTP
自身是難以實現這種消息推送效果的
HTTP
要想實現類似的效果,就需要基于“輪詢”的機制
- 玩家 1 在思考中,尚未落子
- 玩家 2,每隔一段時間(每隔
1s
,500ms
…),就主動地給服務器發起一個請求,問看看當前玩家 1 落子了沒有
很明顯,像這樣的輪詢操作,開銷是比較大的,成本也是比較高的
- 如果輪詢間隔時間長,玩家 1 落子之后,玩家 2 就不能及時拿到結果
- 如果輪詢間隔時間短,雖然即時性得到改善,但是玩家 2 不得不浪費更多的機器資源(尤其是帶寬)
這就類似于去餐館吃飯
- 每隔 1 分鐘,就去前臺看一眼,問問老板,我的飯好了沒——輪詢
- 我直接找個角落坐下來,玩手機,啥時候飯做好了,老板就端過來了——消息推送
因此,websocket
就是實現消息推送的一個主要的方式
報文格式
Websocket
也是一個應用層協議,下層是基于 TCP
的-
FIN
:代表當前是不是一個結束報文
RSV
:保留位,可能以后有什么用,但現在還沒任何用處opcode
:描述了當前這個websocket
報文是什么類型- 表示當前這是一個文本幀,還是一個二進制幀
- 表示當前這是一個
ping
幀,還是一個pong
幀(發ping
回pong
)
Payload len
:表示當前數據包攜帶的數據載荷長度- 這個字段本身就是一個變長的,一個
websocket
數據報能承載的載荷長度是非常非常長的
- 這個字段本身就是一個變長的,一個
Payload Data
:實際報文要傳輸的數據載荷
握手過程(建立連接過程)
使用一個網頁端,嘗試和服務器建立 websocket
連接
- 網頁端會先給服務器發起一個
HTTP
請求,這個HTTP
請求中會帶有特殊的header
,比如:Connection: Upgrade
Upgrade: Websocket
- 這兩個
header
其實就是在告知服務器,我們要進行協議升級。如果服務器支持websocket
,就會返回一個特殊的HTTP
響應,這個響應的狀態碼是 101(切換協議)
- 客戶端和服務器之間就開始使用
websocket
進行通信了
這個過程就類似于:
- 你跟外國人進行對話,你說:can you speak chinese?
- 對面說:yes
- 然后你們就開始用中文進行交流了