WebSockets - общение с сервером
Сеть в значительной степени построена на парадигме запроса / ответа HTTP. Клиент загружает веб-страницу, а затем ничего не происходит, пока пользователь не перейдет на следующую страницу. Примерно в 2005 году AJAX начал делать Интернет более динамичным. Тем не менее, вся связь HTTP управляется клиентом, что требует взаимодействия с пользователем или периодического опроса для загрузки новых данных с сервера.
Технологии, которые позволяют серверу отправлять данные клиенту в тот самый момент, когда он знает, что новые данные доступны, существуют уже довольно давно. Они носят такие имена, как"Push" или же “Comet”.
С участием long polling, клиент открывает HTTP-соединение с сервером, которое остается открытым до отправки ответа. Каждый раз, когда на сервере появляются новые данные, он отправляет ответ. Длинный опрос и другие методы работают достаточно хорошо. Однако у всех них есть одна проблема: они несут накладные расходы HTTP, что не делает их подходящими для приложений с низкой задержкой. Например, многопользовательский шутер в браузере или любая другая онлайн-игра с компонентом реального времени.
Вывод сокетов в Интернет
Спецификация Web Socket определяет API, устанавливающий "сокетные" соединения между веб-браузером и сервером. С точки зрения непрофессионала, между клиентом и сервером существует постоянное соединение, и обе стороны могут начать отправку данных в любое время.
Соединение с веб-сокетом можно просто открыть с помощью конструктора -
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
ws- это новая схема URL-адресов для подключений WebSocket. Есть такжеwss, для безопасного соединения WebSocket таким же образом https используется для безопасных HTTP-соединений.
Немедленное присоединение некоторых обработчиков событий к соединению позволяет узнать, когда соединение открыто, получены входящие сообщения или произошла ошибка.
Второй аргумент принимает необязательный subprotocols. Это может быть строка или массив строк. Каждая строка должна представлятьsubprotocol имя и сервер принимает только одно из переданных subprotocolsв массиве. Принятыйsubprotocol можно определить путем доступа к свойству протокола объекта 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);
};
Связь с сервером
Как только у нас будет соединение с сервером (когда запускается событие open), мы можем начать отправку данных на сервер, используя метод 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. Чтобы указать формат полученного двоичного файла, установите для свойства binaryType объекта WebSocket значение 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. Для одновременного поддержания большого количества открытых соединений требуется архитектура, обеспечивающая высокий уровень параллелизма при низких затратах на производительность.