要理解socket.io ,不得不談談websockethtml
在html5以前,由於http協議是無狀態的,要實現瀏覽器與服務器的實時通信,若是不使用 flash、applet 等瀏覽器插件的話,就須要按期輪詢服務器來獲取信息。這形成了必定的延遲和大量的網絡通信。隨着HTML5 的出現,這一狀況有望完全改觀,它就是 WebSocket 。理論上,Socket能幹的事Websocket都能完成,這與須要實現與服務器實時通訊的應用來講,如從羊腸小道進入了高速公路。那麼,使用Websocket咱們要作些什麼呢?html5
首先,咱們得先看看websocket的工做機制web
工做流程:ajax
瀏覽器經過 JavaScript 向服務器發出創建 WebSocket 鏈接的請求,鏈接創建之後,客戶端和服務器端就能夠經過 TCP 鏈接直接交換數據。由於 WebSocket 鏈接本質上就是一個 TCP 鏈接,因此在數據傳輸的穩定性和數據傳輸量的大小方面,和傳統輪詢以技術比較,具備很大的性能優點。json
爲了創建一個 WebSocket 鏈接,客戶端瀏覽器首先要向服務器發起一個 HTTP 請求,這個請求和一般的 HTTP 請求不一樣,包含了一些附加頭信息,其中附加頭信息」Upgrade: WebSocket」代表這是一個申請協議升級的 HTTP 請求,服務器端解析這些附加的頭信息而後產生應答信息返回給客戶端,客戶端和服務器端的 WebSocket 鏈接就創建起來了,雙方就能夠經過這個鏈接通道自由的傳遞信息,而且這個鏈接會持續存在直到客戶端或者服務器端的某一方主動的關閉鏈接。跨域
協議規範:瀏覽器
一個典型的websocket發起請求到響應請求的例子以下安全
客戶端到服務端: GET / HTTP/1.1 Connection:Upgrade Host:127.0.0.1:8088 Origin:null Sec-WebSocket-Extensions:x-webkit-deflate-frame Sec-WebSocket-Key:puVOuWb7rel6z2AVZBKnfw== Sec-WebSocket-Version:13 Upgrade:websocket 服務端到客戶端: HTTP/1.1 101 Switching Protocols Connection:Upgrade Server:beetle websocket server Upgrade:WebSocket Date:Mon, 26 Nov 2013 23:42:44 GMT Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:content-type Sec-WebSocket-Accept:FCKgUr8c7OsDsLFeJTWrJw6WO8Q=
這是一個握手的http請求,它與普通的http請求有一些區別,首先請求和響應的,」Upgrade:WebSocket」表示請求的目的就是要將客戶端和服務器端的通信協議從 HTTP 協議升級到 WebSocket 協議。從客戶端到服務器端請求的信息裏包含有」Sec-WebSocket-Extensions」、「Sec-WebSocket-Key」這樣的頭信息。這是客戶端瀏覽器須要向服務器端提供的握手信息,服務器端解析這些頭信息,並在握手的過程當中依據這些信息生成一個 28 位的安全密鑰並返回給客戶端,以代表服務器端獲取了客戶端的請求,贊成建立 WebSocket 鏈接。服務器
當握手成功後,這個時候tcp鏈接已在經創建了,客戶發送上來的時候就是純純的數據了。不過服務端要判斷何時是一次數據請求的開始,何時是請求的結束。在websocket中,因爲瀏覽端和服務端已經打好招呼,如我發送的內容爲utf-8 編碼,若是我發送0x00,表示包的開始,若是發送了0xFF,就表示包的結束了。這就解決了黏包的問題。websocket
從握手的協議能夠看出,若是咱們要使用Websocket,咱們須要一個實現Websocket協議規範的服務器,這不在咱們討論的範圍。
值得一提的是:websocket是能夠和http共用監聽端口的,也就是它能夠公用端口完成socket任務。
Socket.io
主角終於上場了,聽了上面對Websocket的介紹以後,你是否是想,socket.io就是對Websocket的封裝呢,而且實現了Websocket的服務端代碼。不錯,可是不徹底正確。剛纔咱們說到,在WebSocket沒有出現以前,實現與服務端的實時通信能夠經過輪詢來完成任務.。Socket.io將Websocket和輪詢(Polling)機制以及其它的實時通訊方式封裝成了通用的接口,而且在服務端實現了這些實時機制的相應代碼。也就是說,Websocket僅僅是Socket.io實現實時通訊的一個子集。
那麼,Socket.io都實現了Polling中的那些通訊機制呢?
- Adobe® Flash® Socket
- AJAX long polling
- AJAX multipart streaming
- Forever Iframe
- JSONP Polling
Adobe® Flash® Socket 大部分PC瀏覽器都支持的socket模式,不過是經過第三方嵌入到瀏覽器,不在W3C規範內,因此可能將逐步被淘汰,何況,大部分的手機瀏覽器都不支持這種模式。
AJAX long polling 這個很好理解,全部瀏覽器都支持這種方式,就是定時的向服務器發送請求,缺點是會給服務器帶來壓力而且出現信息更新不及時的現象。
AJAX multipart streaming 這是在XMLHttpRequest對象上使用某些瀏覽器(好比說Firefox)支持的multi-part標誌。Ajax請求被髮送給服務器端並保持打開狀態(掛起狀態),每次須要向客戶端發送信息,就尋找一個掛起的的http請求響應給客戶端,而且全部的響應都會經過統一鏈接來寫入
var xhr = $.ajaxSettings.xhr(); xhr.multipart =true; xhr.open('GET', 'ajax', true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { processEvents($.parseJSON(xhr.responseText)); } }; xhr.send(null);
Forever Iframe (永存的Iframe)技術涉及了一個置於頁面中的隱藏Iframe標籤,該標籤的src屬性指向返回服務器端事件的servlet路徑。每次在事件到達時,servlet寫入並刷新一個新的script標籤,該標籤內部帶有JavaScript代碼,iframe的內容被附加上這一script標籤,標籤中的內容就會獲得執行。這種方式的缺點是接和數據都是由瀏覽器經過HTML標籤來處理的,所以你沒有辦法知道鏈接什麼時候在哪一端已被斷開了,而且Iframe標籤在瀏覽器中將被逐步取消使用。
JSONP Polling JSONP輪詢基本上與HTTP輪詢同樣,不一樣之處則是JSONP能夠發出跨域請求,詳細請搜索查詢jsonp的內容。