為什么前端項(xiàng)目不都采用 WebSocket?
在前端圈子里面,WebSocket 一直自帶 “高端感”,甚至有些中小廠在面試中會(huì)把 WebSocket 作為技術(shù)難點(diǎn)來問。
畢竟,WebSocket 能做到 全雙工通信,還能讓前端和后端像打電話一樣實(shí)時(shí)對話,聽上去就是 HTTP 的“終極替代品”。
那問題來了:既然 WebSocket 這么強(qiáng),為什么今天的 Web 應(yīng)用沒有全面拋棄 HTTP,只用 WebSocket?
你可能會(huì)想:微信、釘釘這些聊天軟件,不也是靠類似的技術(shù)支撐的嗎?它們能支撐上億用戶同時(shí)在線,那咱們的業(yè)務(wù)系統(tǒng)用 WebSocket,不就能統(tǒng)一交互方式、實(shí)時(shí)性直接拉滿了?
很遺憾,事情遠(yuǎn)沒有這么簡單。
如果你真把所有接口都塞進(jìn) WebSocket,不僅不會(huì)變輕松,反而會(huì)掉進(jìn)一個(gè)又一個(gè)大坑。
今天,我們就來拆解一下:
- 為什么會(huì)出現(xiàn) WebSocket?
- WebSocket 的優(yōu)勢都有什么?
- WebSocket 的缺陷都有啥?
- 實(shí)際開發(fā)中,WebSocket、SSE、HTTP 各自應(yīng)該怎么選?
為什么會(huì)出現(xiàn) WebSocket?
在 WebSocket 出現(xiàn)之前,前端要想實(shí)現(xiàn)“實(shí)時(shí)通信”,基本只能靠兩種老辦法:
- 輪詢(Polling)
- 前端每隔幾秒發(fā)一次請求問:“有新數(shù)據(jù)嗎?”
- 缺點(diǎn)是顯而易見的:浪費(fèi)帶寬,延遲還高。
- 長輪詢(Long Polling)
- 前端發(fā)起請求,服務(wù)端不立刻返回,而是等到有新數(shù)據(jù)才響應(yīng)。
- 響應(yīng)完了,前端再發(fā)起新的請求。
- 延遲問題解決了一點(diǎn),但依舊有大量連接在反復(fù)創(chuàng)建、銷毀。
這兩種方案其實(shí)都不好。
所以,在 2011 年,WebSocket 協(xié)議(RFC 6455) 橫空出世。
它的核心思想很簡單:
- 先用一次 HTTP 握手(Upgrade),然后“升級”成一條持久化的 TCP 連接。
- 從此以后,前后端可以像發(fā)短信一樣隨時(shí)互發(fā)消息,不再需要頻繁建立 HTTP 請求。
這在當(dāng)年絕對是革命性的體驗(yàn):實(shí)時(shí)性大幅提升,同時(shí) 服務(wù)器壓力也大幅度下降。
也正是因?yàn)檫@樣,WebSocket 一度被視為 “Web 實(shí)時(shí)通信的未來”。
WebSocket 的優(yōu)勢都有什么?
雖然現(xiàn)在大家對 WebSocket 的評價(jià)趨于理性,但不得不承認(rèn),它依舊有一些“別人替代不了”的獨(dú)家優(yōu)勢:
1. 所有消息走一條連接,時(shí)序可控
傳統(tǒng) HTTP 請求是 一次一條通道,并行時(shí)序靠隊(duì)列調(diào)度,沒法保證嚴(yán)格的先后順序。
而 WebSocket 不一樣:所有請求、響應(yīng)、通知消息都在同一條連接上傳輸。
這意味著你能精準(zhǔn)掌控消息的時(shí)序:誰先誰后,完全由你決定。
2. 一次鑒權(quán),狀態(tài)長期有效
在 HTTP 世界里,每次請求都得帶上 Token、Cookie 等鑒權(quán)信息,服務(wù)端要一遍遍校驗(yàn)。
WebSocket 則更簡單:連接建立時(shí)完成一次認(rèn)證,后續(xù)所有消息都基于同一個(gè)連接。換句話說,它天然就是“有狀態(tài)”的通信方式,管理起來省心很多。
看起來是不是很爽?
但很遺憾,優(yōu)勢只有這兩條。 剩下的都是問題.....
WebSocket 的缺陷都有啥
光看上面的介紹,你會(huì)感覺 WebSocket 真爽。
但是,如果你真的想要把 所有接口都搬到 WebSocket 上時(shí),很快就會(huì)被教育了。
因?yàn)?WebSocket 帶來的問題,往往比它解決的問題還多:
1. 認(rèn)證機(jī)制不如 HTTP 簡單
握手階段可以帶 Cookie 或 Token,但一旦連接建立,后續(xù)就是裸 TCP 流了。
想用 Header 做認(rèn)證?不好意思,已經(jīng)沒有 HTTP 頭了。
這就意味著你需要自己在消息體里定義認(rèn)證字段,或者額外維護(hù)一套“請求上下文”。
2. 跨域風(fēng)險(xiǎn)更高
HTTP 有 CORS 來保護(hù),WebSocket 默認(rèn)是允許跨域的。
如果不額外校驗(yàn) Origin 頭,那么就非常容易出現(xiàn)數(shù)據(jù)泄露的問題。
3. 請求與響應(yīng)要自己匹配
HTTP 天然是一問一答。
但是,WebSocket 沒這個(gè)約束,你必須用 request_id 來區(qū)分不同請求的響應(yīng),不然消息一亂就麻煩大了。
4. 中間件和生態(tài)缺失
HTTP 里日志、監(jiān)控、路由、緩存都有現(xiàn)成中間件。
但是,WebSocket 世界?幾乎得自己造輪子,連調(diào)試都麻煩。
5. 部署和代理更復(fù)雜
不是所有代理、負(fù)載均衡器都默認(rèn)支持 WebSocket。
配置不當(dāng)?shù)脑挘?/span>Upgrade 頭可能被吃掉,導(dǎo)致連接直接掛掉。
所以說,WebSocket 很酷,但坑點(diǎn)也很硬核。
你要是把 CRUD 接口都放進(jìn)去,絕對是“自找麻煩”。
WebSocket、SSE、HTTP 各自應(yīng)該怎么選
那么根據(jù)以上內(nèi)容,大家應(yīng)該就可以知道:WebSocket 是不可以無腦使用的。
那么具體應(yīng)該怎么用呢?
1. 常規(guī)請求:老老實(shí)實(shí)用 HTTP
像用戶登錄、商品下單、列表查詢這類 標(biāo)準(zhǔn) CRUD 操作,HTTP 永遠(yuǎn)是最優(yōu)解。
2. 單向推送:優(yōu)先 SSE(EventSource)
如果你的場景是 服務(wù)端推消息給前端,比如:
- 系統(tǒng)通知
- 訂單進(jìn)度更新
- 股票/輿情行情
這類單向?qū)崟r(shí)推送,SSE 更合適:
3. 雙向交互:再考慮 WebSocket
只有在確實(shí)需要 雙向通信 的時(shí)候,才該上 WebSocket,比如:
- 聊天系統(tǒng)
- 在線協(xié)同編輯
- 實(shí)時(shí)白板、游戲?qū)?zhàn)
這種場景下,客戶端要告訴服務(wù)端“我訂閱了哪個(gè)頻道”,服務(wù)端再有針對性地推送。
給大家一個(gè)表單,來更清楚的展示 websocket、SSE、長輪詢、HTTP 的使用場景:
圖片





























