Websocket与服务器通信
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连接。保持大量连接同时打开需要一种以低性能成本获得高并发性的体系结构。