1. 程式人生 > >web socket教程

web socket教程

ava url 序列 缺陷 一個表 場景 嘗試 console 不支持

web socket是一種網絡通信協議,很多網頁應用中都會使用到它,比如聊天室,選票等等.


一、為什麽需要WebSocket?

HTTP是無連接(無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。采用這種方式可以節省傳輸時間)

HTTP是無狀態(HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快)

HTTP 協議有一個缺陷:通信只能由客戶端發起。HTTP 協議做不到服務器主動向客戶端推送信息。

這種http單向請求的特點,如果服務器有連續的狀態變化,客戶端要獲知就非常麻煩。我們只能使用“輪詢”:每隔一段時候,就發出一個詢問,了解服務器有沒有新的信息。最典型的場景就是聊天室,選票

輪詢的效率低,非常浪費資源(因為必須不停連接,或者 HTTP 連接始終打開)。因此,工程師們一直在思考,有沒有更好的方法。WebSocket 就是這樣發明的。

二、WebSocket介紹。

所有瀏覽器都已經支持了。

在JavaScript 中創建了Web Socket 之後,會有一個HTTP 請求發送到瀏覽器以發起連接。在取得服務器響應後,建立的連接會使用HTTP 升級從HTTP 協議交換為WebSocket 協議。

它的最大特點就是,服務器可以主動向客戶端推送信息,客戶端也可以主動向服務器發送信息,是真正的雙向平等對話,屬於服務器推送技術的一種。

使用自定義協議而非HTTP 協議的好處是:能夠在客戶端和服務器之間發送非常少量的數據,而不必擔心HTTP 那樣字節級的開銷。由於傳遞的數據包很小,因此Web Sockets 非常適合移動應用。沒有同源限制,客戶端可以與任意服務器通信。

三、WebSocket使用。

1要創建Web Socket,先實例一個WebSocket 對象並傳入要連接的URL:

var socket = new WebSocket("ws://www.example.com/server.php");

註意,必須給WebSocket 構造函數傳入絕對URL。同源策略對Web Sockets 不適用,因此可以通過它打開到任何站點的連接。至於是否會與某個域中的頁面通信,則完全取決於服務器。

實例化了WebSocket 對象後,瀏覽器就會馬上嘗試創建連接。與XHR 類似,WebSocket 也有一個表示當前狀態的readyState 屬性。不過,這個屬性的值與XHR 並不相同,

WebSocket.OPENING (0):正在建立連接。

WebSocket.OPEN (1):已經建立連接。

WebSocket.CLOSING (2):正在關閉連接。

WebSocket.CLOSE (3):已經關閉連接。

WebSocket 沒有readystatechange 事件;不過,它有其他事件,對應著不同的狀態。readyState的值永遠從0 開始。

要關閉Web Socket 連接,可以在任何時候調用close()方法。

socket.close();

調用了close()之後,readyState 的值立即變為2(正在關閉),而在關閉連接後就會變成3。

2. 發送和接收數據

Web Socket 打開之後,就可以通過連接發送和接收數據。要向服務器發送數據,使用send()方法

並傳入任意字符串,例如:var socket = new WebSocket("ws://www.example.com/server.php");

socket.send("Hello world!");

因為Web Sockets 只能通過連接發送純文本數據,所以對於復雜的數據結構,在通過連接發送之前,必須進行序列化。下面的例子展示了先將數據序列化為一個JSON 字符串,然後再發送到服務器:

var message = {

time: new Date(),

text: "Hello world!",

clientId: "asdfp8734rew"

};

socket.send(JSON.stringify(message));

接下來,服務器要讀取其中的數據,就要解析接收到的JSON 字符串。

當服務器向客戶端發來消息時,WebSocket 對象就會觸發message 事件。這個message 事件與其他傳遞消息的協議類似,也是把返回的數據保存在event.data 屬性中。

socket.onmessage = function(event){

var data = event.data;

//處理數據

};

與通過send()發送到服務器的數據一樣,event.data 中返回的數據也是字符串。如果你想得到其他格式的數據,必須手工解析這些數據。

3. 其他事件

WebSocket 對象還有其他三個事件,在連接生命周期的不同階段觸發。

? open:在成功建立連接時觸發。

? error:在發生錯誤時觸發,連接不能持續。

? close:在連接關閉時觸發。

WebSocket 對象不支持DOM 2 級事件偵聽器,因此必須使用DOM 0 級語法分別定義每個事件處理程序。

var socket = new WebSocket("ws://www.example.com/server.php");

socket.onopen = function(){

alert("Connection established.");

};

socket.onerror = function(){

alert("Connection error.");

};

socket.onclose = function(){

alert("Connection closed.");

};

在這三個事件中,只有close 事件的event 對象有額外的信息。這個事件的事件對象有三個額外的屬性:wasClean、code 和reason。其中,wasClean 是一個布爾值,表示連接是否已經明確地關閉;code 是服務器返回的數值狀態碼;而reason 是一個字符串,包含服務器發回的消息。可以把這些信息顯示給用戶,也可以記錄到日誌中以便將來分析。

socket.onclose = function(event){

console.log("Was clean? " + event.wasClean + " Code=" + event.code + " Reason="+ event.reason);

};

web socket教程