基於 WebSocket 的 WebQQ聊天室
WebSocket 是什麼?
WebSocket 是一種網路通訊協議。RFC6455 定義了它的通訊標準。
WebSocket 是 HTML5 開始提供的一種在單個 TCP 連線上進行全雙工通訊的協議。
為什麼需要 WebSocket ?
*瞭解計算機網路協議的人,應該都知道:HTTP 協議是一種無狀態的、無連線的、單向的應用層協議。它採用了請求/響應模型。通訊請求只能由客戶端發起,服務端對請求做出應答處理。
這種通訊模型有一個弊端:HTTP 協議無法實現伺服器主動向客戶端發起訊息。
這種單向請求的特點,註定瞭如果伺服器有連續的狀態變化,客戶端要獲知就非常麻煩。大多數 Web 應用程式將通過頻繁的非同步JavaScript和XML(AJAX)請求實現長輪詢。輪詢的效率低,非常浪費資源(因為必須不停連線,或者 HTTP 連線始終開啟)。*
因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發明的。WebSocket 連線允許客戶端和伺服器之間進行全雙工通訊,以便任一方都可以通過建立的連線將資料推送到另一端。WebSocket 只需要建立一次連線,就可以一直保持連線狀態。這相比於輪詢方式的不停建立連線顯然效率要大大提高。
傳統http請求:
websocket請求:
特點:
(1)服務端可以主動推送資訊,屬於伺服器推送技術的一種。 (2)建立在TCP協議之上,服務端的實現比較容易。 (3)與HTTP協議有著良好的相容性,預設埠也是80和443,並且握手階段採用HTTP協議,因此握手時不容易遮蔽,能通過各種HTTP代理伺服器。 (4)資料格式比較輕量,效能開銷小,通訊高效。 (5)可以傳送文字,也可以傳送二進位制資料。 (6)沒有同源限制,客戶端可以與任意伺服器通訊。 (7)協議識別符號是ws(如果加密,則為wss),伺服器網址就是URL。
WebSocket 如何工作?
Web瀏覽器和伺服器都必須實現 WebSockets 協議來建立和維護連線。由於 WebSockets 連線長期存在,與典型的HTTP連線不同,對伺服器有重要的影響。
基於多執行緒或多程序的伺服器無法適用於 WebSockets,因為它旨在開啟連線,儘可能快地處理請求,然後關閉連線。任何實際的 WebSockets 伺服器端實現都需要一個非同步伺服器。
什麼是輪詢?
輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對伺服器發出HTTP請求,然後由伺服器返回最新的資料給客戶端的瀏覽器。由CPU定時發出詢問,依序詢問每一個周邊裝置是否需要其服務,有即給予服務,服務結束後再問下一個周邊,接著不斷周而復始。
在WEB上來說就是客戶端一直向服務端發起請求,服務端返回資料,不論返回什麼都會再次向服務端傳送請求。
那麼這樣的一種技術優點顯而易見,實現容易;但是缺點也非常明顯,效率很低。而且當訪問量大時,伺服器的壓力是非常大的。
WebSocket 屬性
以下是 WebSocket 物件的屬性。假定我們使用了以上程式碼建立了 Socket 物件:
屬性 描述
Socket.readyState 只讀屬性 readyState 表示連線狀態,可以是以下值:
0 - 表示連線尚未建立。
1 - 表示連線已建立,可以進行通訊。
2 - 表示連線正在進行關閉。
3 - 表示連線已經關閉或者連線不能開啟。
Socket.bufferedAmount 只讀屬性 bufferedAmount 已被 send() 放入正在佇列中等
待傳輸,但是還沒有發出的 UTF-8 文字位元組數。
WebSocket 事件
以下是 WebSocket 物件的相關事件。假定我們使用了以上程式碼建立了 Socket 物件:
事件 事件處理程式 描述
open Socket.onopen 連線建立時觸發
message Socket.onmessage 客戶端接收服務端資料時觸發
error Socket.onerror 通訊發生錯誤時觸發
close Socket.onclose 連線關閉時觸發
WebSocket 方法
以下是 WebSocket 物件的相關方法。假定我們使用了以上程式碼建立了 Socket 物件:
方法 描述
Socket.send() 使用連線傳送資料
Socket.close() 關閉連線
WebSocket 例項
WebSocket 協議本質上是一個基於 TCP 的協議。
為了建立一個 WebSocket 連線,客戶端瀏覽器首先要向伺服器發起一個 HTTP 請求,這個請求和通常的 HTTP 請求不同,包含了一些附加頭資訊,其中附加頭資訊"Upgrade: WebSocket"表明這是一個申請協議升級的 HTTP 請求,伺服器端解析這些附加的頭資訊然後產生應答資訊返回給客戶端,客戶端和伺服器端的 WebSocket 連線就建立起來了,雙方就可以通過這個連線通道自由的傳遞資訊,並且這個連線會持續存在直到客戶端或者伺服器端的某一方主動的關閉連線。