記一次我被面試官問得爆炸的經歷。
簡歷一時爽,面試火葬場。
1. Websocket如何實現長連接的?
TCP是持久連接、全雙工
TCP是持久連接,建立TCP連接是3次握手,關閉TCP連接是4次揮手。TCP連接是由通信雙方(應用層)來決定什么時候關閉,其本身是一個持久連接。TCP連接可以進行全雙工通信,因為雙方都知道對方是誰
HTTP只能單向通信、無狀態
Http協議只能單向通信的原因是:Serve沒有保存Http客戶端的信息(無狀態的),想要通信的時候找不到人。而Http1.1協議新增的keep-alive Header之后,Server會保存連接,即長連接。雖然Comet等基於長鏈接的輪詢技術,實現了全雙工通信;但是每次都是http請求,一堆沒用的信息(http head),浪費資源。而且本質沒有變化,都需要客戶端請求才能獲得數據,增加了keep-alive請求頭只是可以通過一條通道請求多次。
而HTTP的 request - response 模式,純粹是人為規定的,並不存在技術上的問題。說白了就是,HTTP規定,服務器只能響應請求,而不能主動發送數據。
至於添加WebSocket特性,是為了更好、更靈活,輕量的與服務器通訊。因為WebSocket提供了簡單的消息規范,可以更快的適應長連接的環境,其實現在HTTP協議自身就可以做,但是不太輕便。
http協議本身是沒有持久通信能力的,但是我們在實際的應用中,是很需要這種能力的,所以WebSocket協議由此而生,於2011年被IETF定為標准RFC6455,並被RFC7936所補充規范。
並且在HTML5標准中增加了有關WebSocket協議的相關api,所以只要實現了HTML5標准的客戶端,就可以與支持WebSocket協議的服務器進行全雙工的持久通信了。
WebSocket的持久連接
WebSocket協議實現全雙工通信、以及持久連接的一個前提是,它是基於TCP的。
WebSocket協議也需要通過已建立的TCP連接來傳輸數據。具體實現上是通過http協議建立通道,然后在此基礎上用真正的WebSocket協議進行通信。
WebSocket 本質上跟 HTTP 完全不一樣,只不過為了兼容性,WebSocket 的握手是以 HTTP 的形式發起的,
下面是WebSocket協議請求頭:
- Sec-WebSocket-Version表明客戶端所使用的協議版本
- 響應的狀態碼101,表示切換了協議,說明利用http建立傳輸層的TCP連接,之后便與http協議無關的
- Sec-WebSocket-Key是一個Base64編碼值,由瀏覽器隨機生成。是一種驗證服務端支不支持websocket的算法
- Sec-Websocket-accept=base64(sha1(key)+常量),如果返回的accept和算出來的相同,說明服務端支持
WebSocket協議的優缺點
優點:
· WebSocket協議一旦建議后,互相溝通所消耗的請求頭是很小的
· 服務器可以主動向客戶端推送消息了
缺點:
· 少部分瀏覽器不支持,瀏覽器支持的程度與方式有區別
WebSocket協議的應用場景
· 即時聊天通信
· 多玩家游戲
· 在線協同編輯/編輯
· 實時數據流的拉取與推送
· 體育/游戲實況
· 實時地圖位置