書名: 新時期的Node.js入門作者名: 李鍇本章字數: 1301字更新時間: 2019-12-12 17:05:43
2.7 WebSocket
WebSocket可以看作是HTTP協議的升級版,它同樣是基于TCP協議的應用層協議,主要是為了彌補HTTP協議的無持久化和無狀態等缺陷而誕生的。
WebSocket提供了客戶端和服務器之間全雙工的通信機制。
2.7.1 保持通話
當客戶端發起一個請求時,客戶端和服務器之間首先需要建立TCP連接,然后才能使用更高層的HTTP協議來解析數據。
HTTP是非持久化的,當用戶發起一個request,服務器會隨之返回一個response,那么這個HTTP連接就結束了,TCP連接也隨之關閉。如果客戶端想要繼續訪問服務器的內容,還需要重新建立TCP連接。對于連續的請求來說,這樣會在TCP握手上浪費不少時間。
為了改進這一問題,瀏覽器在請求頭里增加了Connection: Keep-Alive這一字段,當服務器收到帶有這一頭部的請求時會保持TCP連接不斷開,同時也會在response中增加這一字段,這樣瀏覽器和服務器之間只要建立一次TCP連接就可以進行多次HTTP通信。
在HTTP 1.1版本中,Connection: Keep-Alive被加入到標準之中,同時所有的連接都會被默認保持,除非手動指定Connection: Close。此外,為了避免無限制的長連接,服務器也會設置一個timeout屬性,用來指定該連接最長可以保持時間。
keep-alive的最大優點在于其避免了多次的TCP握手帶來的性能浪費;但還是有一些缺陷,其本質上還是使用HTTP進行通信,對于協議本身沒有什么改進。
2.7.2 為什么要有WebSocket
假設我們要開發一個新聞類網站,該網站會一直將最新的新聞推送到頁面上而不需要用戶進行刷新操作,在WebSocket之前的HTTP協議中,服務器無法主動向客戶端推送數據,對于這種情況有兩種解決方案。
(1)客戶端每隔幾秒就發起Ajax請求,如果返回不為空,就將內容展示在頁面上。
(2)使用長輪詢,服務器收到客戶端的請求后,如沒有新的內容,就保持阻塞,當新內容產生后再發送response給客戶端。
這兩種做法的缺點都很明顯。第一種可能客戶端發送了很多請求才能得到一個新內容,第二種則是在服務器獲得新內容前都無法關閉socket,會占用很多系統資源。
WebSocket可以實現瀏覽器與服務器的全雙工通信,它和傳統的jsonp、comet等解決方案不同,不必瀏覽器發送請求后再由服務器返回消息,而是可以由服務器主動發起向瀏覽器的數據傳輸。
WebSocket的請求頭和HTTP很相似,下面是一個WebSocket header和服務器的response。

服務器返回以下消息:

在請求頭中,Connection字段必須設置成Upgrade,表示客戶端希望連接升級。
Upgrade字段必須設置WebSocket,表示希望升級到WebSocket協議。
Sec-WebSocket-Key是隨機的字符串,服務器端會用這些數據來構造出一個SHA-1的信息摘要。服務器會給這個隨機的字符串再加上一個特殊字符串“ 258EAFA5-E 914-47DA-95CA-C5AB0DC85B11”,然后計算SHA-1摘要,之后進行BASE-64編碼,將結果作為Sec-WebSocket-Accept頭的值返回給客戶端。
“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”這一字符串是一個GUID,其本身并沒有特別的含義,選擇這個字符串的原因只是這個字符串不大可能被WebSocket之外的協議用到(協議本身描述如下:which is unlikely to be used by network endpoints that do not understand the WebSocket Protocol)。
Sec-WebSocket-Version表示支持的WebSocket版本。RFC6455要求使用的版本是13,之前草案的版本均應當被棄用。
Origin字段是可選的,通常用來表示在瀏覽器中發起此WebSocket連接所在的頁面,類似于Referer。但是,與Referer不同的是,Origin只包含了協議和主機名稱。
其他一些定義在HTTP協議中的字段,如Cookie等,也可以在WebSocket中使用。
2.7.3 WebSocket與Node
在NPM中有很多支持WebSocket的第三方模塊,這里使用WS這一第三方模塊。
下面是一個簡單的例子。
代碼2.19 JavaScript連接WebScoket

代碼2.20 Node實現的WebSocket服務器

在Node里,比較出名的WebSocket模塊還有Socket.IO,常被拿來做在線的聊天或者推送服務。讀者有興趣可以自行了解。
- 精通JavaScript+jQuery:100%動態網頁設計密碼
- Python數據分析入門與實戰
- Instant QlikView 11 Application Development
- C語言實驗指導及習題解析
- 編程數學
- Java網絡編程核心技術詳解(視頻微課版)
- HTML5開發精要與實例詳解
- NGUI for Unity
- Python Digital Forensics Cookbook
- Web開發的平民英雄:PHP+MySQL
- Puppet 5 Beginner's Guide(Third Edition)
- INSTANT PLC Programming with RSLogix 5000
- Scratch編程入門與算法進階(第2版)
- Mastering High Performance with Kotlin
- 設計模式之禪