還記得曾經風靡一時的 QQ 秀聊天室嗎?那時,還在上初、高中的我們,QQ 是最常用的聊天交友工具;而 QQ 秀聊天室的出現打破了只能按條件查找好友的侷限性,大家可以隨意進入聊天室房間,進行在線聊天。懷念那個穿着最酷炫的 QQ 秀的我在聊天室閃亮登場,質樸的問出一句:“有 GG/MM 嗎?”
WebSocket 的誕生
隨着互聯網的發展,網上出現了各種聊天室軟件,各種新奇的玩法,卻再也找不到當年那種純真的感覺了。當然了,無論是曾經的聊天室,還是如今的視頻彈幕,吸引人的地方就在於實時溝通交流。要實現類似實時交互的應用場景,需要低延遲、高及時的技術。
曾經,很多網站為了實現上述場景,所用的技術都是輪詢。即每隔一段時間(如每 1 秒),由瀏覽器對服務器發出 HTTP 請求,詢問服務器有沒有新的信息,然後由服務器返回最新的數據給客户端。這種傳統的輪詢模式存在很明顯的缺點,即瀏覽器需要不斷的向服務器發出請求,然而 HTTP 請求包含較長的請求頭,真正有效的數據可能只佔一小部分,這樣顯然會浪費一部分帶寬資源。那有沒有更好的方法呢?
WebSocket 應運而生。WebSocket 協議誕生於 2008 年,在 2011 年成為國際標準,並且 WebSocket 同樣是 HTML 5 規範的組成部分之一。WebSocket 是一種全新的協議,它將 TCP 的 Socket(套接字)應用在了 web page 上,從而使通信雙方建立起一個保持在活動狀態連接通道,並且屬於全雙工(雙方同時進行雙向通信)。WebSocket 協議更好的節省了服務器資源和帶寬,並且能夠更實時地進行通訊。
相比 HTTP 協議,WebSocket 究竟有哪些不同呢?
HTTP vs WebSocket
HTTP 協議是半雙工協議,也就是説在同一時間點只能處理一個方向的數據傳輸,屬於單向傳輸。在客户端向服務器發起連接之前,服務器並不知道有這個連接。發起一個請求,得到一個響應,通信便結束了,客户端和服務器也“忘記了彼此”。不過現在可以通過 Cookie 使客户端保持某種狀態,以便服務器可以識別客户端。
而 WebSocket 協議是全雙工的,服務器可以隨時主動給客户端下發數據,可以雙向發送或接受信息,屬於雙向傳輸。WebSocket 可以通過客户端和服務器的握手建立連接,並且連接一直保持“打開”狀態,不僅僅是一個請求 + 一個響應。首先,客户端會先發起請求建立連接,若服務器接受了此請求,則將建立雙向通信。然後,服務器和客户端就可以進行信息交互了,直到客户端或服務器發送消息將其關閉為止。
當然,WebSocket 和 HTTP 也是有聯繫的。因為 WebSocket 需要先通過 HTTP 協議的 101 狀態碼建立連接。為了創建 WebSocket 連接,需要通過瀏覽器發起請求,等待服務器進行迴應,這個過程通常稱為“握手”(Handshaking)。
一個典型的 WebSocket 握手請求如下:
客户端請求:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost.com
Origin: http://localhost.com
Sec-WebSocket-Key: aN3cRrW/n8NuIgdhy2VJFX==
Sec-WebSocket-Version: 13
服務器迴應:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: pFDoeB2FAdLlXgESz0UT2v7hp0s=
Sec-WebSocket-Location: ws://localhost.com/
字段説明:
- Connection 字段必須為 Upgrade,表示客户端希望連接升級。
- Upgrade 字段必須為 WebSocket,表示希望升級到 WebSocket 協議。
- Sec-WebSocket-Key 的值是隨機字符串,服務器端會用這些數據來構造出一個SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一個特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然後計算 SHA-1 ,再進行 Base64 編碼,將結果做為“Sec-WebSocket-Accept”頭的值,並返回給客户端。這樣可以儘量避免普通 HTTP 請求被誤認為 WebSocket 協議。
- Sec-WebSocket-Version 字段表示支持的 WebSocket 版本。RFC6455 要求使用的版本是13,之前草案的版本均應當棄用。
- 其他一些定義在 HTTP 協議中的字段,如 Cookie 等,也可以在 WebSocket 中使用。
WebSocket 使用 ws 或 wss 的統一標識符,類似於 HTTP/HTTPS。其中 wss 表示使用了 TLS 的 WebSocket。例如:
ws://localhost.com/api
wss://securelocalhost.com/api
WebSocket 與 HTTP/HTTPS 使用相同的 TCP 端口。默認情況下,WebSocket 協議使用 80 端口;運行在 TLS 之上時,默認使用 443 端口。
WebSocket 的優勢
作為“後起之秀”,到如今的廣泛應用,毋庸置疑 WebSocket 擁有很多優點:
- 較少的資源浪費
在連接創建後,服務器和客户端之間交互時,傳輸的數據包頭部相對較小。相對於 HTTP 請求每次都要攜帶完整的頭部,資源浪費顯著減少了。
- 更強的實時性
由於 WebSocket 協議是全雙工的,所以服務器可以隨時主動給客户端傳輸數據。相對於 HTTP 請求需要等待客户端發起請求服務端才能響應,延遲明顯更少。
- 保持長連接
與 HTTP 不同的是,WebSocket 需要先創建連接,這就使得其成為了一種有狀態的協議。而 HTTP 請求可能需要在每個請求都攜帶狀態信息(如身份認證等)。
- 更好的二進制支持
WebSocket 定義了二進制幀,相對 HTTP,可以更輕鬆地處理二進制內容。
- 更好的壓縮效果
相對於 HTTP 壓縮,WebSocket 在適當的擴展支持下,可以沿用之前內容的上下文,在傳遞類似的數據時,顯著地提高壓縮率。
不同的業務場景如何選擇
相比較 WebSocket 和 HTTP,可以説 HTTP 請求比 WebSocket 更簡單,但是也有侷限性。在不同的使用場景可以選擇更合適的協議。
目前互聯網上大多數網站都是直接加載網頁,除了單擊加載新頁面之外,交互工作都很少。在這種場景下沒有必要保持長連接,使用 WebSocket 會顯得過於“笨重”。一般的網頁都會使用靜態資源,例如 Image 圖片,Javascript 或 CSS 文件等。為了加載更快,這些靜態資源都需要進行緩存,而且它們可能並不來自同一個域名,這時當然使用 HTTP 更為輕便快捷。
HTTP 協議的每個請求都需要發送一次請求頭,而 WebSocket 僅在初始請求建立連接中攜帶頭信息(當然了,傳遞消息中也會有一些開銷,但都是比較小的)。因此,如果想持續發送多個消息,使用 Websocket 會更節省資源。如果要開發一個客户端和服務器持續交互的程序,那麼 WebSockets 將是最佳選擇。例如:
- 社交、聊天
社交聊天工具,網站在線諮詢窗口等,這一類聊天應用的特點是低延遲,高及時。其採用 WebSocket 協議,實現了實時溝通交流,以高效的方式滿足溝通的需求。
- 彈幕
看視頻,彈幕少不了,精彩的點評、搞笑的段子,網友之間的實時互動,有時對於一個視頻來説,彈幕才是精華。而發彈幕需要實時顯示,通過 WebSocket 協議可將本地客户端發送的彈幕信息通過服務端全部推送至其他用户的客户端並進行實時展示。
- 在線教育
在線教育近幾年發展迅速,不用出門即可和老師、同學實時溝通、交流。老師佈置作業、學生互動、諮詢老師問題等等都可實時在線進行,此類實時交互都可由 WebSocket 協議支撐完成。
- 位置信息更新的應用
當前移動設備中實時的位置定位、實時的網絡數據更新,使用 HTTP 協議顯得有些笨拙,借用 WebSocket 可以讓數據實時更新更快。
又拍雲 WebSocket 服務產品,突破傳統 CDN 廠商只能加速 HTTP/HTTPS 協議的侷限,將 WebSocket 協議與 CDN 相融合,並結合自身多年 CDN 行業技術經驗,採用多種優化技術,為使用 WS/WSS 協議進行通信的客户提供了優質的加速服務,能有效降低延遲,提升效率。快來搶先體驗!
推薦閲讀
説説 WebSocket,3 分鐘讓你全面認識它
為什麼 HTTPS 比 HTTP 安全