天天看點

WebSocket協定WebSocket與TCP、HTTP的關系WebSocket通訊詳細解讀

使用一個文本編輯器,把下面代碼複制儲存在一個 websocket.html 檔案中,然後隻要在浏覽器中打開它,頁面就會使用 websocket 自動連接配接,發送一個消息,顯示接受到的伺服器響應,然後關閉連接配接。

<!DOCTYPE html>  

<meta charset="utf-8" />  

<title>WebSocket Test</title>  

<script language="javascript"type="text/javascript">  

    var wsUri ="ws://echo.websocket.org/"; 

    var output;  

    function init() { 

        output = document.getElementById("output"); 

        testWebSocket(); 

    }  

    function testWebSocket() { 

        websocket = new WebSocket(wsUri); 

        websocket.onopen = function(evt) { 

            onOpen(evt) 

        }; 

        websocket.onclose = function(evt) { 

            onClose(evt) 

        websocket.onmessage = function(evt) { 

            onMessage(evt) 

        websocket.onerror = function(evt) { 

            onError(evt) 

    function onOpen(evt) { 

        writeToScreen("CONNECTED"); 

        doSend("WebSocket rocks"); 

    function onClose(evt) { 

        writeToScreen("DISCONNECTED"); 

    function onMessage(evt) { 

        writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>'); 

        websocket.close(); 

    function onError(evt) { 

        writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data); 

    function doSend(message) { 

        writeToScreen("SENT: " + message);  

        websocket.send(message); 

    function writeToScreen(message) { 

        var pre = document.createElement("p"); 

        pre.style.wordWrap = "break-word"; 

        pre.innerHTML = message; 

        output.appendChild(pre); 

    window.addEventListener("load", init, false);  

</script>  

<h2>WebSocket Test</h2>  

<div id="output"></div>  

</html>

申請一個WebSocket對象,參數是需要連接配接的伺服器端的位址,同http協定使用http://開頭一樣,WebSocket協定的URL使用ws://開頭,另外安全的WebSocket協定使用wss://開頭。。

       var wsUri ="ws://echo.websocket.org/"; 

       websocket = new WebSocket(wsUri); 

WebSocket對象一共支援四個消息 onopen, onmessage, onclose和onerror,

我們可以看出所有的操作都是采用消息的方式觸發的,這樣就不會阻塞UI,使得UI有更快的響應時間,得到更好的使用者體驗。

當Browser和WebSocketServer連接配接成功後,會觸發onopen消息;

如果連接配接失敗,發送、接收資料失敗或者處理資料出現錯誤,browser會觸發onerror消息;

當Browser接收到WebSocketServer發送過來的資料時,就會觸發onmessage消息,參數evt中包含server傳輸過來的資料;

當Browser接收到WebSocketServer端發送的關閉連接配接請求時,就會觸發onclose消息。

WebSocket與http協定一樣都是基于TCP的,是以他們都是可靠的協定,Web開發者調用的WebSocket的send函數在browser的實作中最終都是通過TCP的系統接口進行傳輸的。

WebSocket和Http協定一樣都屬于應用層的協定,那麼他們之間有沒有什麼關系呢?答案是肯定的,WebSocket在建立握手連接配接時,資料是通過http協定傳輸的,但是在建立連接配接之後,真正的資料傳輸階段是不需要http協定參與的。

WebSocket協定WebSocket與TCP、HTTP的關系WebSocket通訊詳細解讀

 從下圖可以明顯的看到,分三個階段:

打開握手

資料傳遞

關閉握手

WebSocket協定WebSocket與TCP、HTTP的關系WebSocket通訊詳細解讀

顯示了WebSocket主要的三步 浏覽器和 伺服器端分别做了那些事情。

WebSocket協定WebSocket與TCP、HTTP的關系WebSocket通訊詳細解讀

WebSocket的優點

a)、伺服器與用戶端之間交換的标頭資訊很小,大概隻有2位元組;

b)、用戶端與伺服器都可以主動傳送資料給對方;

c)、不用頻率建立TCP請求及銷毀請求,減少網絡帶寬資源的占用,同時也節省伺服器資源;

當Web應用程式調用new WebSocket(url)接口時,Browser就開始了與位址為url的WebServer建立握手連接配接的過程。

1. Browser與WebSocket伺服器通過TCP三向交握建立連接配接,如果這個建立連接配接失敗,那麼後面的過程就不會執行,Web應用程式将收到錯誤消息通知。

2. 在TCP建立連接配接成功後,Browser/UA通過http協定傳送WebSocket支援的版本号,協定的字版本号,原始位址,主機位址等等一些列字段給伺服器端。

3.     WebSocket伺服器收到Browser/UA發送來的握手請求後,如果資料包資料和格式正确,用戶端和伺服器端的協定版本号比對等等,就接受本次握手連接配接,并給出相應的資料回複,同樣回複的資料包也是采用http協定傳輸。 

4.     Browser收到伺服器回複的資料包後,如果資料包内容、格式都沒有問題的話,就表示本次連接配接成功,觸發onopen消息,此時Web開發者就可以在此時通過send接口想伺服器發送資料。否則,握手連接配接失敗,Web應用程式會收到onerror消息,并且能知道連接配接失敗的原因。 

這個握手很像HTTP,但是實際上卻不是,它允許伺服器以HTTP的方式解釋一部分handshake的請求,然後切換為websocket

WebScoket協定中,資料以幀序列的形式傳輸。

考慮到資料安全性,用戶端向伺服器傳輸的資料幀必須進行掩碼處理。伺服器若接收到未經過掩碼處理的資料幀,則必須主動關閉連接配接。

伺服器向用戶端傳輸的資料幀一定不能進行掩碼處理。用戶端若接收到經過掩碼處理的資料幀,則必須主動關閉連接配接。

針對上情況,發現錯誤的一方可向對方發送close幀(狀态碼是1002,表示協定錯誤),以關閉連接配接。

WebSocket協定WebSocket與TCP、HTTP的關系WebSocket通訊詳細解讀

使用Wireshark監控到的上面WebSocket例子的資料。

GET / HTTP/1.1

Upgrade: websocket

Connection: Upgrade

Host: echo.websocket.org

Origin: null

Pragma: no-cache

Cache-Control: no-cache

Sec-WebSocket-Key: Qcgtb1RJ6HceeTRLPFux/A==

Sec-WebSocket-Version: 13

Sec-WebSocket-Extensions: x-webkit-deflate-frame

Cookie: __utma=9925811.951031439.1365242028.1365980711.1366068689.5; __utmc=9925811; __utmz=9925811.1365242028.1.1.utmcsr=websocket.org|utmccn=(referral)|utmcmd=referral|utmcct=/

HTTP/1.1 101 Web Socket Protocol Handshake

Upgrade: WebSocket

Sec-WebSocket-Accept: 84Qpane33QhxOmcz8bGkFdE1AHk=

Server: Kaazing Gateway

Date: Tue, 16 Apr 2013 09:51:25 GMT

Access-Control-Allow-Origin: null

Access-Control-Allow-Credentials: true

Access-Control-Allow-Headers: content-type

Access-Control-Allow-Headers: authorization

Access-Control-Allow-Headers: x-websocket-extensions

Access-Control-Allow-Headers: x-websocket-version

Access-Control-Allow-Headers: x-websocket-protocol

..a[

J6>h..8a/.{x%.0y..WebSocket rocks..i.....

繼續閱讀