WebSockets - 与服务器通信

Web主要围绕HTTP的请求/响应范例构建.客户端加载网页,然后在用户点击下一页之前没有任何操作.大约在2005年,AJAX开始让网络感觉更有活力.仍然,所有HTTP通信都由客户端引导,这需要用户交互或定期轮询以从服务器加载新数据.

使服务器能够将数据发送到客户端的技术知道新数据可用的那一刻已经存在了很长一段时间.它们的名称如"推""彗星".

长轮询,客户端打开与服务器的HTTP连接,在发送响应之前将其保持打开状态.每当服务器实际拥有新数据时,它就会发送响应.长轮询和其他技术工作得很好.但是,所有这些都存在一个问题,它们带来了HTTP的开销,这使得它们不适合低延迟应用.例如,浏览器中的多人射击游戏或任何其他具有实时组件的在线游戏.

将套接字带到网上

Web Socket规范定义了在Web浏览器和服务器之间建立"套接字"连接的API.通俗地说,客户端和服务器之间存在持久连接,双方都可以随时开始发送数据.

可以使用构造函数 :  

var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);

ws是WebSocket连接的新URL架构。 还有wss,用于安全的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(您的消息)方法向服务器发送数据。 它过去仅支持字符串,但是在最新规范中,它现在也可以发送二进制消息。 要发送二进制数据,请使用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连接。 同时保持大量连接打开需要一种以低性能成本获得高并发性的体系结构。