websocket

什麼是websocket?
websocket是一種網絡協議,是在HTTP基礎上作了一些優化的協議,與HTTP無直接關係。web

HTTP協議
HTTP(超文本傳輸協議):規定了web瀏覽器如何從web服務器獲取文檔和想web服務器提交表單內容,以及web服務器如何響應這些請求和提交返回給瀏覽器。
HTTP的第一個版本叫作HTTP/0.9,是一種爲互聯網原數據傳輸服務的簡單協議。由RFC 1945[6]定義的HTTP/1.0進一步完善了這個協議。它容許消息以類MIME消息的格式傳送,它包括傳輸數據的元信息和對請求/響應語義的修飾。HTTP/1.0沒有充分考慮到分層代理,緩存的,以及持久連接和虛擬主機的需求得影響。
HTTP/1.1,版本對1.0版本作了優化,開始支持長鏈接和緩存。瀏覽器

爲何須要webSocket?
由於HTTP協議有一個缺陷:通訊只能由客戶端發起,服務器不能實時發送最新數據給客戶端。要是我偏要最新的數據怎麼辦?能夠用Ajax輪訓,Ajax輪訓就是一個定時器,每隔多少時間讓它請求一下服務器端。這個webSocket能夠實現服務器端主動給客戶端實時更新數據。
好比說;查詢天氣,如今天氣如何?客戶端請求服務端,服務端反饋:如今天氣晴,過一會天氣變了,用戶還有請求一次才能看到天氣的變化,而不是服務端實時更新反饋數據,體驗能更好。
image.png
HTTP與WebSocket連接方式對比(最大的區別)緩存

image.png
webSocket請求報文服務器

image.png

webSocket響應報文
image.pngwebsocket

報文頭字段含義網絡

  • Connection 必須設置 Upgrade,表示客戶端但願鏈接升級。
  • Upgrade 字段必須設置 Websocket,表示但願升級到 Websocket 協議。
  • Sec-WebSocket-Key 是隨機的字符串,服務器端會用這些數據來構造出一個 SHA-1 的信息摘要。把 「Sec-WebSocket-Key」 加上一個特殊字符串 「258EAFA5-E914-47DA-95CA-C5AB0DC85B11」,而後計算 SHA-1 摘要,以後進行 BASE-64 編碼,將結果作爲 「Sec-WebSocket-Accept」 頭的值,返回給客戶端。如此操做,能夠儘可能避免普通 HTTP 請求被誤認爲 Websocket 協議。
  • Sec-WebSocket-Version 表示支持的 Websocket 版本。RFC6455 要求使用的版本是 13,以前草案的版本均應當棄用。
  • Sec-WebSocket-Protocal是一個用戶定義的字符串,用來區分同URL下,不一樣的服務所須要的協議。
  • Origin 字段是可選的,一般用來表示在瀏覽器中發起此 Websocket 鏈接所在的頁面,相似於 Referer。可是,與 Referer 不一樣的是,Origin 只包含了協議和主機名稱。

    其餘一些定義在 HTTP 協議中的字段,如 Cookie 等,也能夠在 Websocket 中使用。socket

webSocket的特色
(1)創建在 TCP 協議之上,服務器端的實現比較容易。
(2)與 HTTP 協議有着良好的兼容性。默認端口也是80和443,而且握手階段採用 HTTP 協議,所以握手時不容易屏蔽,能經過各類 HTTP 代理服務器。
(3)數據格式比較輕量,性能開銷小,通訊高效。
(4)能夠發送文本,也能夠發送二進制數據。
(5)沒有同源限制,客戶端能夠與任意服務器通訊。
(6)協議標識符爲ws(若是加密爲wss)服務器網址就是url
(7)不受同源策略的限制函數

webSocket的使用性能

建立webSocket測試

var Socket = new WebSocket(url);

Websocket方法:
一、Socket.send()
send(data) 方法使用鏈接傳輸數據。

二、Socket.close()
close() 方法用於終止任何現有鏈接

<script>
     //建立webSocket
     var socket = new WebSocket('ws://echo.websocket.org/');
     socket.onopen = function(){
         //發送數據
         socket.send('hello world');
    }
     socket.onmessage = function(e){
         console.log(e.data);
         socket.close();//終止連接,下面的 你好,世界傳不了了
         socket.send('你好!世界')           
    }
 </script>

websocket屬性
image.png

<script>
        var socket = new WebSocket('ws://echo.websocket.org/');
        console.log('before---',socket.readyState);//表示還沒有鏈接
        socket.onopen = function(){
            console.log('打開鏈接',socket.readyState);//已鏈接
            socket.send('你好,服務端');
        }
        socket.onmessage = function(e){
            //下面能夠e.data接收消息
            console.log('message接收服務端信息' + e.data,socket.readyState);//已鏈接
            socket.close();
            console.log('closeing鏈接正在關閉中',socket.readyState);//正在進行關閉  
        }
        socket.onclose = function(){
            console.log('close鏈接已經關閉',socket.readyState);//鏈接已經關閉
        }
    </script>

執行結果以下:
image.png

websocket事件

onopen
onopen屬性用來指定鏈接成功以後的回調函數,看上面代碼,咱們在鏈接成功以後打印一個鏈接成功,而且調用send方法。這裏若是要是指定多個回調函數,須要使用addEventListener方法。

onclose
和onopen同樣的使用,用來指定關閉鏈接的回調。
onmessage
指定接收到服務器數據後的回調,能夠在回調中經過參數.data獲取到返回的數據。
onerror
指定發生錯誤時的回調
send
用來發送數據,不只僅是普通字符串文本,也能夠是其餘類型的數據(好比ArrayBuffer )。
bufferedAmount
能夠獲取當前還有多少數據沒有發出去,用來判斷是否發送結束。

if(socket.bufferedAmount === 0){
    console.log("發送完畢");
}else{
    console.log("還有", socket.bufferedAmount, "數據沒有發送");
}

注:WebSocket.org 提供了一個專門用來測試WebSocket的服務器"ws://echo.websocket.org"

Websocket優勢

  1. 客戶端與服務器均可以主動傳送數據給對方;
  2. 不用頻率建立TCP請求及銷燬請求,減小網絡帶寬資源的佔用,同時也節省服務器資源;

官網http://websocketd.com/

相關文章
相關標籤/搜索