Web主要圍繞HTTP的請求/回應範例構建。客戶端加載網頁,然後在用戶點擊下一頁之前沒有任何操作。大約在2005年,AJAX開始讓網路感覺更有活力。仍然,所有HTTP通信都由客戶端引導,這需要用戶交互或定期輪詢以從伺服器加載新數據。
使伺服器能夠在知道新數據可用的瞬間將數據發送到客戶端的技術已存在很長時間了。它們的名稱如“Push”或“Comet”。
將套接字引入Web
Websocket規範定義了在Web流覽器和服務器之間建立“套接字”連接的API。通俗地說,客戶端和服務器之間存在持久連接,雙方都可以隨時開始發送數據。
可以使用構造函數簡單地打開Web套接字連接 -
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ws
是WebSocket連接的新URL模式。對於安全的WebSocket連接,也有同樣的方式,https用於安全的HTTP連接。
通過立即將某些事件處理程式附加到連接,可以瞭解何時打開連接,接收傳入消息或發生錯誤。
第二個參數接受可選的子協議。它可以是字串或字串數組。每個字串應代表一個子協議名稱,伺服器只接受數組中傳遞的子協議之一。可以通過訪問WebSocket對象的協議屬性來確定接受的子協議。
// When the connection is open, send some data to the server
connection.onopen = function () {
connection.send('Ping'); // Send the message 'Ping' to the server
};
// Log errors
connection.onerror = function (error) {
console.log('WebSocket Error ' + error);
};
// Log messages from the server
connection.onmessage = function (e) {
console.log('Server: ' + e.data);
};
與伺服器通信
當連接到伺服器(當觸發打開事件時),我們就可以使用連接對象上的send(message)
方法開始向伺服器發送數據。它過去只支持字串,但在最新的規範中,它現在也可以發送二進位消息。要發送二進位數據,請使用Blob
或ArrayBuffer
對象。
// Sending String
connection.send('your message');
// Sending canvas ImageData as ArrayBuffer
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
connection.send(binary.buffer);
// Sending file as Blob
var file = document.querySelector('input[type = "file"]').files[0];
connection.send(file);
同樣,伺服器可能隨時向我們發送消息。每當發生這種情況時,onmessage
回調就會觸發。回調接收事件對象,並且可以通過data
屬性訪問實際消息。
WebSocket還可以接收最新規範中的二進位消息。可以Blob或ArrayBuffer格式接收二進位幀。要指定接收到的二進位檔的格式,請將WebSocket對象的binaryType
屬性設置為“blob”或“arraybuffer”。默認格式為’blob’。
// Setting binaryType to accept received binary as either 'blob' or 'arraybuffer'
connection.binaryType = 'arraybuffer';
connection.onmessage = function(e) {
console.log(e.data.byteLength); // ArrayBuffer object if binary
};
WebSocket的另一個新增功能是擴展。使用擴展,可以發送壓縮,多路複用等幀。
// Determining accepted extensions
console.log(connection.extensions);
跨域通信
作為一種現代協議,跨源通信直接融入WebSocket。WebSocket支持任何域上的各方之間的通信。伺服器決定是將其服務提供給所有客戶端還是僅提供給在一組明確定義的域上的服務。
代理伺服器
每種新技術都帶來一系列新問題。在WebSocket的情況下,它與代理伺服器相容,代理伺服器在大多數公司網路中調解HTTP連接。WebSocket協議使用HTTP升級系統(通常用於HTTP/SSL)將HTTP連接“升級”到WebSocket連接。某些代理伺服器不喜歡這樣,會丟棄連接。因此,即使給定客戶端使用WebSocket協議,也可能無法建立連接。
伺服器端
使用WebSocket為伺服器端應用程式創建了一個全新的使用模式。雖然傳統的伺服器堆疊(如LAMP)是圍繞HTTP請求/回應週期設計的,但它們通常不能很好地處理大量開放的WebSocket連接。保持大量連接同時打開需要一種以低性能成本獲得高併發性的體系結構。