WebSocket是什么原理?為什么能實(shí)現(xiàn)持久化連接?
為了更好的理解WebSocket,我們需要從HTTP開(kāi)始說(shuō)起。因?yàn)楹芏鄷r(shí)候,大家都喜歡拿WebSocket和HTTP做比較。
HTTP的生命周期,通過(guò)Request來(lái)界定,一個(gè)Request和一個(gè)Response,這次HTTP請(qǐng)求也就結(jié)束了。
在HTTP1.1中,允許發(fā)送多個(gè)Request和接收多個(gè)Response,但無(wú)論如何,Request永遠(yuǎn)等于Response。
很多網(wǎng)站為了實(shí)現(xiàn)實(shí)時(shí)的信息傳遞,都會(huì)使用輪詢(xún)技術(shù),輪詢(xún)有兩種,一種是ajax輪詢(xún),一種是長(zhǎng)輪詢(xún)(long poll)。
ajax輪詢(xún)的原理很簡(jiǎn)單,讓瀏覽器每隔幾秒向服務(wù)器發(fā)送一次請(qǐng)求,詢(xún)問(wèn)服務(wù)器是否有新的信息。
客戶(hù)端:有沒(méi)有新信息,沒(méi)有我等會(huì)再問(wèn)(Request)
服務(wù)器:沒(méi)有(Response) 客戶(hù)端:有沒(méi)有,沒(méi)有我等會(huì)再問(wèn)(Request) 服務(wù)器:沒(méi)有(Response) 客戶(hù)端:有沒(méi)有新信息,沒(méi)有我等會(huì)再問(wèn)(Request) 服務(wù)器:有,發(fā)給你了(Response) |
長(zhǎng)輪詢(xún)與ajax輪詢(xún)相似,不同的是,當(dāng)客戶(hù)端發(fā)起請(qǐng)求后,如果沒(méi)有消息,就一直不返回Response,直到有新消息為止。
客戶(hù)端:有沒(méi)有新信息,沒(méi)有不要回我(Request)
…… 服務(wù)器:現(xiàn)在有了,給你(Response) |
以上兩種方式,都在不斷地建立HTTP連接,只有客戶(hù)端發(fā)起請(qǐng)求時(shí),服務(wù)端才能回應(yīng),服務(wù)端是不能主動(dòng)發(fā)起的。
而且HTTP還是一個(gè)無(wú)狀態(tài)協(xié)議,服務(wù)器不會(huì)保留與客戶(hù)交易時(shí)的任何狀態(tài),這樣做的好處是大大減輕了服務(wù)器的記憶負(fù)擔(dān),保持較快的響應(yīng)速度。
不過(guò)因此也產(chǎn)生了一些問(wèn)題。客戶(hù)端要不斷地發(fā)送HTTP請(qǐng)求,每次都要帶上較長(zhǎng)的頭部,真正有效的數(shù)據(jù)可能很少,浪費(fèi)很多帶寬資源,也給服務(wù)器增加了壓力。
好了,我們的主角WebSocket終于可以登場(chǎng)了。
相對(duì)HTTP來(lái)說(shuō),WebSocket是一種持久化的協(xié)議。它會(huì)基于HTTP協(xié)議,來(lái)完成一部分握手,之后就脫離HTTP,完全采用WebSocket了。
建立WebSocket連接的過(guò)程為:
- 客戶(hù)端發(fā)起HTTP請(qǐng)求,經(jīng)過(guò)3次握手建立TCP連接,HTTP請(qǐng)求里存放WebSocket支持的版本號(hào)等信息。
- 服務(wù)器收到客戶(hù)端握手請(qǐng)求后,回饋數(shù)據(jù)。
以上兩個(gè)步驟完成后,HTTP握手部分完成,協(xié)議升級(jí)為WebSocket,此時(shí)服務(wù)器就不再需要客戶(hù)端發(fā)起請(qǐng)求,再響應(yīng)請(qǐng)求了,可以主動(dòng)推送信息給客戶(hù)端了。
客戶(hù)端:我要建立WebSocket協(xié)議。
服務(wù)器:好的,已經(jīng)升級(jí)為WebSocket協(xié)議了。 客戶(hù)端:有信息的時(shí)候,推送給我。 服務(wù)器:好的,有信息會(huì)推給你。 服務(wù)器:有信息了,給你。 服務(wù)器:又有信息了,給你。 …… |
只需經(jīng)過(guò)一次HTTP請(qǐng)求,服務(wù)器就能源源不斷地向客戶(hù)端推送信息了!
從客戶(hù)端主動(dòng)詢(xún)問(wèn),變成服務(wù)器主動(dòng)推送,解決了服務(wù)器上資源消耗較多的問(wèn)題。
以上便是WebSocket原理以及實(shí)現(xiàn)持久化連接的過(guò)程。