WebSockets - Краткое руководство

В буквальном смысле рукопожатие можно определить как захват и рукопожатие двумя людьми за правую руку, что символизирует приветствие, поздравление, согласие или прощание. В информатике квитирование - это процесс, который обеспечивает синхронизацию сервера со своими клиентами. Подтверждение связи - основная концепция протокола Web Socket.

На следующей диаграмме показано рукопожатие сервера с различными клиентами -

Веб-сокеты - Определение

Веб-сокеты определяются как двусторонняя связь между серверами и клиентами, что означает, что обе стороны общаются и обмениваются данными одновременно.

Ключевые моменты веб-сокетов: true concurrency и optimization of performance, что приводит к более отзывчивым и многофункциональным веб-приложениям.

Описание протокола веб-сокетов

Этот протокол определяет полнодуплексную связь с нуля. Веб-сокеты делают шаг вперед в обеспечении функциональных возможностей настольных компьютеров в веб-браузерах. Он представляет собой эволюцию, которую долгое время ждали в веб-технологиях клиент / сервер.

Основные особенности веб-сокетов следующие:

  • Протокол веб-сокетов стандартизируется, что означает, что с помощью этого протокола возможна связь между веб-серверами и клиентами в реальном времени.

  • Веб-сокеты трансформируются в кроссплатформенный стандарт для связи в реальном времени между клиентом и сервером.

  • Этот стандарт допускает новый вид приложений. Компании, использующие веб-приложения в реальном времени, могут ускорить работу с помощью этой технологии.

  • Самым большим преимуществом Web Socket является то, что он обеспечивает двустороннюю связь (полный дуплекс) через одно TCP-соединение.

URL

HTTP имеет собственный набор схем, таких как http и https. Протокол веб-сокетов также имеет аналогичную схему, определенную в его шаблоне URL.

На следующем изображении показан URL-адрес веб-сокета в токенах.

Поддержка браузера

Последняя спецификация протокола Web Socket определяется как RFC 6455 - предлагаемый стандарт.

RFC 6455 поддерживается различными браузерами, такими как Internet Explorer, Mozilla Firefox, Google Chrome, Safari и Opera.

Прежде чем приступить к изучению веб-сокетов, необходимо взглянуть на существующие методы, которые используются для duplex communicationмежду сервером и клиентом. Они следующие -

  • Polling
  • Длинный опрос
  • Streaming
  • Постбек и AJAX
  • HTML5

Опрос

Опрос можно определить как метод, который выполняет периодические запросы независимо от данных, существующих в передаче. Периодические запросы отправляются синхронно. Клиент делает периодический запрос к Серверу через указанный интервал времени. Ответ сервера включает в себя доступные данные или какое-то предупреждающее сообщение.

Длинный опрос

Длительный опрос, как следует из названия, включает в себя похожую технику, например опрос. Клиент и сервер поддерживают соединение активным до тех пор, пока не будут получены некоторые данные или не истечет время ожидания. Если соединение потеряно по каким-либо причинам, клиент может начать заново и выполнить последовательный запрос.

Длительный опрос - это не что иное, как улучшение производительности по сравнению с процессом опроса, но постоянные запросы могут замедлить процесс.

Потоковое

Считается лучшим вариантом для передачи данных в реальном времени. Сервер поддерживает соединение с клиентом открытым и активным до тех пор, пока не будут получены требуемые данные. В этом случае соединение называется открытым на неопределенный срок. Потоковая передача включает заголовки HTTP, которые увеличивают размер файла, увеличивая задержку. Это можно считать серьезным недостатком.

AJAX

AJAX основан на Javascript XmlHttpRequestОбъект. Это сокращенная форма асинхронного Javascript и XML.XmlHttpRequestObject позволяет выполнять Javascript без перезагрузки всей веб-страницы. AJAX отправляет и получает только часть веб-страницы.

Фрагмент кода вызова AJAX с XmlHttpRequest Объект выглядит следующим образом -

var xhttp;

if (window.XMLHttpRequest) {
   xhttp = new XMLHttpRequest();
} else {
   // code for IE6, IE5
   xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

Основные недостатки AJAX по сравнению с Web Sockets являются -

  • Они отправляют заголовки HTTP, что увеличивает общий размер.
  • Связь полудуплексная.
  • Веб-сервер потребляет больше ресурсов.

HTML5

HTML5 - это надежная платформа для разработки и проектирования веб-приложений. Основные столпы включаютMark-up, CSS3 и Javascript API вместе.

На следующей диаграмме показаны компоненты HTML5 -

Приведенный ниже фрагмент кода описывает объявление HTML5 и его тип документа.

<!DOCTYPE html>

Зачем нам нужны веб-сокеты?

Интернет задумывался как набор страниц на языке гипертекстовой разметки (HTML), связывающих друг друга, чтобы сформировать концептуальную сеть информации. С течением времени количество статических ресурсов увеличивалось, они становились более богатыми, например изображениями, и стали частью веб-структуры.

Развитые серверные технологии, которые позволили создать динамические серверные страницы - страницы, содержимое которых было создано на основе запроса.

Вскоре потребность иметь больше динамических веб-страниц привело к доступности языка динамической гипертекстовой разметки (DHTML). Все благодаря JavaScript. В последующие годы мы увиделиcross frame communication в попытке избежать перезагрузки страницы с последующим HTTP Polling в рамках.

Однако ни одно из этих решений не предлагало действительно стандартизированного кроссбраузерного решения для двунаправленной связи в реальном времени между сервером и клиентом.

Это привело к необходимости использования протокола веб-сокетов. Это привело к полнодуплексной связи, в результате чего все веб-браузеры получили широкие функциональные возможности для настольных компьютеров.

Web Socket представляет собой крупное обновление в истории веб-коммуникаций. До своего существования вся связь между веб-клиентами и серверами основывалась только на HTTP.

Web Socket помогает в динамическом потоке соединений, которые являются постоянными полнодуплексными. Полный дуплекс - это связь с обоих концов со значительной скоростью.

Его называют революционным из-за того, что он позволяет преодолеть все недостатки существующих протоколов.

Веб-сокет для разработчиков и архитекторов

Важность Web Socket для разработчиков и архитекторов -

  • Web Socket - это независимый протокол на основе TCP, но он разработан для поддержки любого другого протокола, который традиционно работал бы только поверх чистого TCP-соединения.

  • Web Socket - это транспортный уровень, поверх которого может работать любой другой протокол. Web Socket API поддерживает возможность определять подпротоколы: библиотеки протоколов, которые могут интерпретировать определенные протоколы.

  • Примеры таких протоколов включают XMPP, STOMP и AMQP. Разработчикам больше не нужно думать в терминах парадигмы HTTP-запроса-ответа.

  • Единственное требование на стороне браузера - запустить библиотеку JavaScript, которая может интерпретировать рукопожатие Web Socket, устанавливать и поддерживать соединение Web Socket.

  • На стороне сервера промышленным стандартом является использование существующих библиотек протоколов, которые работают поверх TCP и используют шлюз веб-сокетов.

На следующей диаграмме описаны функции веб-сокетов -

Соединения Web Socket инициируются через HTTP; HTTP-серверы обычно интерпретируют рукопожатия Web Socket как запрос на обновление.

Веб-сокеты могут быть дополнительным дополнением к существующей среде HTTP и могут предоставить необходимую инфраструктуру для добавления веб-функций. Он основан на более продвинутых полнодуплексных протоколах, которые позволяют передавать данные в обоих направлениях между клиентом и сервером.

Функции веб-сокетов

Веб-сокеты обеспечивают соединение между веб-сервером и клиентом, так что обе стороны могут начать отправку данных.

Шаги для установления соединения с веб-сокетом следующие:

  • Клиент устанавливает соединение с помощью процесса, известного как рукопожатие веб-сокета.

  • Процесс начинается с того, что клиент отправляет серверу обычный HTTP-запрос.

  • Запрошен заголовок Upgrade. В этом запросе он сообщает серверу, что запрос предназначен для подключения к веб-сокету.

  • URL-адреса веб-сокетов используют wsсхема. Они также используются для безопасных соединений через веб-сокеты, которые эквивалентны HTTP.

Простой пример заголовков начального запроса выглядит следующим образом:

GET ws://websocket.example.com/ HTTP/1.1
Origin: http://example.com
Connection: Upgrade
Host: websocket.example.com
Upgrade: websocket

Веб-сокеты играют ключевую роль не только в сети, но и в мобильной индустрии. Важность веб-сокетов указана ниже.

  • Веб-сокеты, как видно из названия, связаны с Интернетом. Интернет состоит из набора методов для некоторых браузеров; это широкая коммуникационная платформа для огромного количества устройств, включая настольные компьютеры, ноутбуки, планшеты и смартфоны.

  • Приложение HTML5, использующее веб-сокеты, будет работать в любом браузере с поддержкой HTML5.

  • Веб-сокет поддерживается в основных операционных системах. Все ключевые игроки мобильной индустрии предоставляют API-интерфейсы Web Socket в собственных нативных приложениях.

  • Веб-сокеты считаются полнодуплексной связью. Подход веб-сокетов хорошо работает для определенных категорий веб-приложений, таких как чат, где обновления как с клиента, так и с сервера передаются одновременно.

Веб-сокеты, часть спецификации HTML5, обеспечивают полнодуплексную связь между веб-страницами и удаленным хостом. Протокол разработан для достижения следующих преимуществ, которые можно рассматривать как ключевые:

  • Reduce unnecessary network traffic and latency с использованием полнодуплексного режима через одно соединение (вместо двух).

  • Streaming through proxies and firewalls, с поддержкой восходящей и нисходящей связи одновременно.

Для связи между ними необходимо инициализировать соединение с сервером от клиента. Для инициализации соединения требуется создание объекта Javascript с URL-адресом на удаленном или локальном сервере.

var socket = new WebSocket(“ ws://echo.websocket.org ”);

Вышеупомянутый URL-адрес - это общедоступный адрес, который можно использовать для тестирования и экспериментов. Сервер websocket.org всегда активен, когда он получает сообщение и отправляет его обратно клиенту.

Это самый важный шаг для обеспечения правильной работы приложения.

Веб-сокеты - События

Существует четыре основных API веб-сокетов events -

  • Open
  • Message
  • Close
  • Error

Каждое из событий обрабатывается путем реализации таких функций, как onopen, onmessage, onclose и onerrorфункции соответственно. Также это можно реализовать с помощью метода addEventListener.

Краткий обзор событий и функций описывается следующим образом -

открыто

Как только соединение между клиентом и сервером установлено, событие open запускается из экземпляра Web Socket. Это называется начальным рукопожатием между клиентом и сервером. Событие, которое возникает после установления соединения, называетсяonopen.

Сообщение

Событие сообщения происходит обычно, когда сервер отправляет какие-то данные. Сообщения, отправляемые сервером клиенту, могут включать текстовые сообщения, двоичные данные или изображения. Когда данные отправляются,onmessage функция запущена.

Закрыть

Событие Close отмечает окончание связи между сервером и клиентом. Закрытие соединения возможно с помощьюoncloseсобытие. Отметив окончание общения с помощьюoncloseсобытие, никакие сообщения не могут быть переданы между сервером и клиентом. Закрытие мероприятия также может произойти из-за плохого подключения.

ошибка

Ошибки отмечаются ошибкой, произошедшей во время общения. Отмечается с помощьюonerror событие. Onerrorвсегда следует за прекращением соединения. Подробное описание каждого события обсуждается в следующих главах.

Веб-сокеты - Действия

События обычно запускаются, когда что-то происходит. С другой стороны, действия предпринимаются, когда пользователь хочет, чтобы что-то произошло. Действия выполняются явными вызовами с использованием функций пользователями.

Протокол Web Socket поддерживает два основных действия, а именно:

  • Отправить( )
  • Закрыть( )

Отправить ( )

Это действие обычно предпочтительнее для некоторого взаимодействия с сервером, которое включает отправку сообщений, которые включают текстовые файлы, двоичные данные или изображения.

Сообщение чата, которое отправляется с помощью действия send (), выглядит следующим образом:

// get text view and button for submitting the message
var textsend = document.getElementById(“text-view”);
var submitMsg = document.getElementById(“tsend-button”);

//Handling the click event
submitMsg.onclick = function ( ) {
   // Send the data
   socket.send( textsend.value);
}

Note - Отправка сообщений возможна только при открытом соединении.

Закрыть ( )

Этот метод означает прощальное рукопожатие. Он полностью разрывает соединение, и никакие данные не могут быть переданы, пока соединение не будет восстановлено.

var textsend = document.getElementById(“text-view”);
var buttonStop = document.getElementById(“stop-button”);

//Handling the click event
buttonStop.onclick = function ( ) {
   // Close the connection if open
   if (socket.readyState === WebSocket.OPEN){
      socket.close( );
   }
}

Также можно намеренно закрыть соединение с помощью следующего фрагмента кода -

socket.close(1000,”Deliberate Connection”);

Как только соединение между клиентом и сервером установлено, событие open запускается из экземпляра Web Socket. Это называется начальным рукопожатием между клиентом и сервером.

Событие, которое возникает после установления соединения, называется onopen. Создание соединений через веб-сокеты действительно просто. Все, что вам нужно сделать, это позвонить вWebSocket constructor и передайте URL-адрес вашего сервера.

Следующий код используется для создания подключения к веб-сокету -

// Create a new WebSocket.
var socket = new WebSocket('ws://echo.websocket.org');

Как только соединение будет установлено, в вашем экземпляре веб-сокета будет запущено событие open.

onopen относится к начальному рукопожатию между клиентом и сервером, которое привело к первой сделке, и веб-приложение готово передать данные.

В следующем фрагменте кода описывается открытие соединения по протоколу Web Socket -

socket.onopen = function(event) {
   console.log(“Connection established”);
   // Display user friendly messages for the successful establishment of connection
   var.label = document.getElementById(“status”);
   label.innerHTML = ”Connection established”;
}

Хорошей практикой является предоставление соответствующей обратной связи пользователям, ожидающим установления соединения с веб-сокетом. Однако всегда отмечается, что соединения через веб-сокеты сравнительно быстрые.

Демонстрация установленного соединения с веб-сокетом задокументирована по указанному URL-адресу - https://www.websocket.org/echo.html

Снимок установки соединения и ответа пользователю показан ниже -

Установление открытого состояния разрешает полнодуплексную связь и передачу сообщений, пока соединение не будет разорвано.

пример

Создание файла client-HTML5.

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      var output;
	
      function init() {
         output = document.getElementById("output");
         testWebSocket();
      }
	
      function testWebSocket() {
         websocket = new WebSocket(wsUri);
			
         websocket.onopen = function(evt) {
            onOpen(evt)
         };
      }
	
      function onOpen(evt) {
         writeToScreen("CONNECTED");
      }
	
      window.addEventListener("load", init, false);
   
   </script>

   <h2>WebSocket Test</h2>
   <div id = "output"></div>

</html>

Результат будет следующим -

Вышеупомянутый файл HTML5 и JavaScript показывает реализацию двух событий Web Socket, а именно:

  • onLoad который помогает в создании объекта JavaScript и инициализации соединения.

  • onOpen устанавливает соединение с сервером, а также отправляет статус.

Как только соединение между клиентом и сервером установлено, openсобытие запускается из экземпляра веб-сокета. Ошибки генерируются за ошибки, которые имеют место при общении. Отмечается с помощьюonerror событие. Onerror всегда следует за прекращением соединения.

В onerrorСобытие запускается, когда между сообщениями происходит что-то не так. Событиеonerror за ним следует разрыв соединения, что является close событие.

Хорошая практика - всегда сообщать пользователю о неожиданной ошибке и пытаться повторно подключить его.

socket.onclose = function(event) {
   console.log("Error occurred.");
	
   // Inform the user about the error.
   var label = document.getElementById("status-label");
   label.innerHTML = "Error: " + event;
}

Когда дело доходит до обработки ошибок, вы должны учитывать как внутренние, так и внешние параметры.

  • Внутренние параметры включают ошибки, которые могут быть сгенерированы из-за ошибок в вашем коде или неожиданного поведения пользователя.

  • Внешние ошибки не имеют ничего общего с приложением; скорее, они связаны с параметрами, которыми нельзя управлять. Самый важный из них - это возможность подключения к сети.

  • Любое интерактивное двунаправленное веб-приложение требует активного подключения к Интернету.

Проверка доступности сети

Представьте, что вашим пользователям нравится ваше веб-приложение, как вдруг сетевое соединение перестает отвечать в процессе выполнения их задачи. В современных настольных и мобильных приложениях обычная задача - проверка доступности сети.

Наиболее распространенный способ сделать это - просто отправить HTTP-запрос на веб-сайт, который должен работать (например, http://www.google.com). Если запрос выполнен успешно, настольный компьютер или мобильное устройство знает, что подключение активно. Точно так же HTML имеетXMLHttpRequest для определения доступности сети.

HTML5, однако, сделал это еще проще и представил способ проверить, может ли браузер принимать веб-ответы. Это достигается с помощью объекта навигатора -

if (navigator.onLine) {
   alert("You are Online");
}else {
   alert("You are Offline");
}

Автономный режим означает, что либо устройство не подключено, либо пользователь выбрал автономный режим на панели инструментов браузера.

Вот как сообщить пользователю, что сеть недоступна, и попытаться повторно подключиться, когда происходит событие закрытия WebSocket:

socket.onclose = function (event) {
   // Connection closed.
   // Firstly, check the reason.
	
   if (event.code != 1000) {
      // Error code 1000 means that the connection was closed normally.
      // Try to reconnect.
		
      if (!navigator.onLine) {
         alert("You are offline. Please connect to the Internet and try again.");
      }
   }
}

Демо для получения сообщений об ошибках

Следующая программа объясняет, как отображать сообщения об ошибках с помощью веб-сокетов.

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      var output;
		
      function init() {
         output = document.getElementById("output");
         testWebSocket();
      }
		
      function testWebSocket() {
         websocket = new WebSocket(wsUri);
			
         websocket.onopen = function(evt) {
            onOpen(evt)
         };
			
         websocket.onclose = function(evt) {
            onClose(evt)
         };
			
         websocket.onerror = function(evt) {
            onError(evt)
         };
      }
		
      function onOpen(evt) {
         writeToScreen("CONNECTED");
         doSend("WebSocket rocks");
      }
		
      function onClose(evt) {
         writeToScreen("DISCONNECTED");
      }
		
      function onError(evt) {
         writeToScreen('<span style = "color: red;">ERROR:</span> ' + evt.data);
      } 
		
      function doSend(message) {
         writeToScreen("SENT: " + message); websocket.send(message);
      }
		
      function writeToScreen(message) {
         var pre = document.createElement("p"); 
         pre.style.wordWrap = "break-word"; 
         pre.innerHTML = message; output.appendChild(pre);
      }
		
      window.addEventListener("load", init, false);
   </script>
	
   <h2>WebSocket Test</h2>
   <div id = "output"></div>
	
</html>

Результат выглядит следующим образом -

В MessageСобытие обычно происходит, когда сервер отправляет какие-то данные. Сообщения, отправляемые сервером клиенту, могут включать текстовые сообщения, двоичные данные или изображения. Когда данные отправляются,onmessage функция запущена.

Это событие действует как ухо клиента серверу. Всякий раз, когда сервер отправляет данные,onmessage событие запускается.

В следующем фрагменте кода описывается открытие соединения по протоколу Web Socket.

connection.onmessage = function(e){
   var server_message = e.data;
   console.log(server_message);
}

Также необходимо учитывать, какие данные можно передавать с помощью веб-сокетов. Протокол веб-сокетов поддерживает текстовые и двоичные данные. Что касается Javascript,text называется строкой, а двоичные данные представлены как ArrayBuffer.

Веб-сокеты одновременно поддерживают только один двоичный формат. Объявление двоичных данных выполняется явно следующим образом:

socket.binaryType = ”arrayBuffer”;
socket.binaryType = ”blob”;

Струны

Строки считаются полезными, поскольку работают с удобочитаемыми форматами, такими как XML и JSON. Всякий раз, когдаonmessage возникает событие, клиент должен проверить тип данных и действовать соответствующим образом.

Фрагмент кода для определения типа данных как String упомянут ниже -

socket.onmessage = function(event){

   if(typeOf event.data === String ) {
      console.log(“Received data string”);
   }
}

JSON (обозначение объектов JavaScript)

Это легкий формат для передачи удобочитаемых данных между компьютерами. Структура JSON состоит из пар ключ-значение.

пример

{
   name: “James Devilson”,
   message: “Hello World!”
}

Следующий код показывает, как обрабатывать объект JSON и извлекать его свойства.

socket.onmessage = function(event) {
   if(typeOf event.data === String ){
      //create a JSON object
      var jsonObject = JSON.parse(event.data);
      var username = jsonObject.name;
      var message = jsonObject.message;
		
      console.log(“Received data string”);
   }
}

XML

Разбор XML несложен, хотя методы различаются от браузера к браузеру. Лучший метод - использовать стороннюю библиотеку, например jQuery.

И в XML, и в JSON сервер отвечает в виде строки, которая анализируется на стороне клиента.

ArrayBuffer

Он состоит из структурированных двоичных данных. Прилагаемые биты расположены в таком порядке, чтобы можно было легко отслеживать положение. ArrayBuffers удобны для хранения файлов изображений.

Получать данные с помощью ArrayBuffers довольно просто. ОператорinstanceOf используется вместо оператора равенства.

Следующий код показывает, как обрабатывать и получать объект ArrayBuffer:

socket.onmessage = function(event) {
   if(event.data instanceof ArrayBuffer ){
      var buffer = event.data;
      console.log(“Received arraybuffer”);
   }
}

Демо-приложение

Следующий программный код показывает, как отправлять и получать сообщения с помощью веб-сокетов.

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      var output;
		
      function init() {
         output = document.getElementById("output");
         testWebSocket();
      }
		
      function testWebSocket() {
         websocket = new WebSocket(wsUri);
			
         websocket.onopen = function(evt) {
            onOpen(evt)
         };
		
         websocket.onmessage = function(evt) {
            onMessage(evt)
         };
		
         websocket.onerror = function(evt) {
            onError(evt)
         };
      }
		
      function onOpen(evt) {
         writeToScreen("CONNECTED");
         doSend("WebSocket rocks");
      }
		
      function onMessage(evt) {
         writeToScreen('<span style = "color: blue;">RESPONSE: ' +
            evt.data+'</span>'); websocket.close();
      }

      function onError(evt) {
         writeToScreen('<span style="color: red;">ERROR:</span> ' + evt.data);
      }
		
      function doSend(message) {
         writeToScreen("SENT: " + message); websocket.send(message);
      }
		
      function writeToScreen(message) {
         var pre = document.createElement("p"); 
         pre.style.wordWrap = "break-word"; 
         pre.innerHTML = message; output.appendChild(pre);
      }
		
      window.addEventListener("load", init, false);
		
   </script>
	
   <h2>WebSocket Test</h2>
   <div id = "output"></div> 
	
</html>

Результат показан ниже.

Closeсобытие отмечает окончание связи между сервером и клиентом. Закрытие соединения возможно с помощьюoncloseсобытие. Отметив окончание общения с помощьюoncloseсобытие, никакие сообщения не могут быть переданы между сервером и клиентом. Закрытие мероприятия также может произойти из-за плохой связи.

В close() метод означает goodbye handshake. Он завершает соединение, и обмен данными невозможен, пока соединение не откроется снова.

Как и в предыдущем примере, мы вызываем close() , когда пользователь нажимает вторую кнопку.

var textView = document.getElementById("text-view");
var buttonStop = document.getElementById("stop-button");

buttonStop.onclick = function() {
   // Close the connection, if open.
   if (socket.readyState === WebSocket.OPEN) {
      socket.close();
   }
}

Также можно передать код и параметры причины, которые мы упоминали ранее, как показано ниже.

socket.close(1000, "Deliberate disconnection");

Следующий код дает полный обзор того, как закрыть или отключить соединение с веб-сокетом.

<!DOCTYPE html>
<html>
   <meta charset = "utf-8" />
   <title>WebSocket Test</title>

   <script language = "javascript" type = "text/javascript">
      var wsUri = "ws://echo.websocket.org/";
      var output;
	
      function init() {
         output = document.getElementById("output");
         testWebSocket();
      }
	
      function testWebSocket() {
         websocket = new WebSocket(wsUri);
		
         websocket.onopen = function(evt) {
            onOpen(evt)
         };
		
         websocket.onclose = function(evt) {
            onClose(evt)
         };
		
         websocket.onmessage = function(evt) {
            onMessage(evt)
         };
		
         websocket.onerror = function(evt) {
            onError(evt)
         };
      }
	
      function onOpen(evt) {
         writeToScreen("CONNECTED");
         doSend("WebSocket rocks");
      }
	
      function onClose(evt) {
         writeToScreen("DISCONNECTED");
      }
	
      function onMessage(evt) {
         writeToScreen('<span style = "color: blue;">RESPONSE: ' + 
            evt.data+'</span>'); websocket.close();
      }
	
      function onError(evt) {
         writeToScreen('<span style = "color: red;">ERROR:</span> '
            + evt.data);
      } 
	
      function doSend(message) {
         writeToScreen("SENT: " + message); websocket.send(message);
      }
	
      function writeToScreen(message) {
         var pre = document.createElement("p"); 
         pre.style.wordWrap = "break-word"; 
         pre.innerHTML = message; 
         output.appendChild(pre);
      }
	
      window.addEventListener("load", init, false);
   </script>
	
   <h2>WebSocket Test</h2>
   <div id = "output"></div>
	
</html>

Результат выглядит следующим образом -

Сервер Web Socket - это простая программа, которая может обрабатывать события и действия Web Socket. Обычно он предоставляет аналогичные методы клиентскому API Web Socket, и большинство языков программирования предоставляют реализацию. На следующей диаграмме показан процесс связи между сервером веб-сокета и клиентом веб-сокета с акцентом на инициированные события и действия.

На следующей диаграмме показан запуск событий сервера и клиента Web Socket.

Подключение к веб-серверу

Сервер Web Socket работает аналогично клиентам Web Socket. Он реагирует на события и при необходимости выполняет действия. Независимо от используемого языка программирования, каждый сервер Web Socket выполняет определенные действия.

Он инициализируется адресом веб-сокета. Он обрабатываетOnOpen, OnClose, и OnMessage событиях, а также отправляет сообщения клиентам.

Создание экземпляра сервера веб-сокетов

Каждому серверу Web Socket нужен действующий хост и порт. Пример создания экземпляра веб-сокета на сервере выглядит следующим образом:

var server = new WebSocketServer("ws://localhost:8181");

Можно использовать любой действительный URL с указанием порта, который ранее не использовался. Очень полезно вести учет подключенных клиентов, поскольку он предоставляет подробную информацию с разными данными или отправляет разные сообщения каждому из них.

Fleck представляет входящие соединения (клиентов) с IwebSocketConnectionинтерфейс. Каждый раз, когда кто-то подключается к нашему сервису или отключается от него, может быть создан или обновлен пустой список.

var clients = new List<IWebSocketConnection>();

После этого мы можем вызвать Startи дождитесь подключения клиентов. После запуска сервер может принимать входящие соединения. В Fleck методу Start требуется параметр, который указывает сокет, который вызвал события -

server.Start(socket) =>
{
});

OnOpen событие

В OnOpenсобытие определяет, что новый клиент запросил доступ, и выполняет начальное рукопожатие. Клиент должен быть добавлен в список и, вероятно, должна быть сохранена относящаяся к нему информация, например IP-адрес. Fleck предоставляет нам такую ​​информацию, а также уникальный идентификатор соединения.

server.Start(socket) ⇒ {

   socket.OnOpen = () ⇒ {
      // Add the incoming connection to our list.
      clients.Add(socket);
   }
	
   // Handle the other events here...
});

Событие OnClose

В OnCloseСобытие возникает всякий раз, когда клиент отключается. Клиент удаляется из списка и сообщает об отключении остальным клиентам.

socket.OnClose = () ⇒ {
   // Remove the disconnected client from the list.
   clients.Remove(socket);
};

Событие OnMessage

В OnMessageСобытие возникает, когда клиент отправляет данные на сервер. Внутри этого обработчика событий входящее сообщение может быть передано клиентам или, возможно, выбрано только некоторые из них.

Процесс прост. Обратите внимание, что этот обработчик принимает строку с именемmessage в качестве параметра -

socket.OnMessage = () ⇒ {
   // Display the message on the console.
   Console.WriteLine(message);
};

Отправить () Метод

В Send()просто передает желаемое сообщение указанному клиенту. Используя Send (), клиенты могут хранить текстовые или двоичные данные.

Работа OnMessage событие выглядит следующим образом -

socket.OnMessage = () ⇒ {
   foreach (var client in clients) {
      // Send the message to everyone!
      // Also, send the client connection's unique identifier in order
      // to recognize who is who.
      client.Send(client.ConnectionInfo.Id + " says: " + message);
   }
};

API - Определение

API, аббревиатура от Application Program Interface, представляет собой набор процедур, протоколов и инструментов для создания программных приложений.

Некоторые важные функции -

  • API определяет, как компоненты программного обеспечения должны взаимодействовать, и API должны использоваться при программировании компонентов графического пользовательского интерфейса (GUI).

  • Хороший API упрощает разработку программы, предоставляя все строительные блоки.

  • REST, который обычно работает по протоколу HTTP, часто используется в мобильных приложениях, социальных веб-сайтах, инструментах гибридных приложений и автоматизированных бизнес-процессах.

  • Стиль REST подчеркивает, что взаимодействие между клиентами и службами улучшается за счет ограниченного количества операций (глаголов).

  • Гибкость обеспечивается за счет распределения ресурсов; их собственные уникальные универсальные идентификаторы ресурсов (URI).

  • REST избегает двусмысленности, потому что каждый глагол имеет определенное значение (GET, POST, PUT и DELETE)

Преимущества Web Socket

Web Socket решает несколько проблем с REST или HTTP в целом -

Двунаправленный

HTTP - это однонаправленный протокол, в котором клиент всегда инициирует запрос. Сервер обрабатывает и возвращает ответ, а затем клиент потребляет его. Web Socket - это двунаправленный протокол, в котором нет предопределенных шаблонов сообщений, таких как запрос / ответ. Либо клиент, либо сервер могут отправить сообщение другой стороне.

Полный дуплекс

HTTP позволяет сообщению запроса идти от клиента к серверу, а затем сервер отправляет ответное сообщение клиенту. В данный момент либо клиент разговаривает с сервером, либо сервер разговаривает с клиентом. Web Socket позволяет клиенту и серверу разговаривать независимо друг от друга.

Одно TCP-соединение

Как правило, новое TCP-соединение инициируется для HTTP-запроса и завершается после получения ответа. Необходимо установить новое TCP-соединение для другого HTTP-запроса / ответа. Для Web Socket соединение HTTP обновляется с использованием стандартного механизма обновления HTTP, и клиент и сервер обмениваются данными через одно и то же TCP-соединение в течение жизненного цикла соединения Web Socket.

На приведенном ниже графике показано время (в миллисекундах), затраченное на обработку N сообщений при постоянном размере полезной нагрузки.

Вот необработанные данные, которые питают этот график -

График и таблица, приведенные выше, показывают, что служебные данные REST возрастают с увеличением количества сообщений. Это верно, потому что многие TCP-соединения должны быть инициированы и завершены, а многие HTTP-заголовки должны быть отправлены и получены.

Последний столбец, в частности, показывает коэффициент умножения количества времени, необходимого для выполнения запроса REST.

На втором графике показано время, необходимое для обработки фиксированного количества сообщений за счет изменения размера полезной нагрузки.

Вот необработанные данные, которые питают этот график -

Этот график показывает, что дополнительные затраты на обработку запроса / ответа для конечной точки REST минимальны, и большая часть времени уходит на инициирование / завершение соединения и соблюдение семантики HTTP.

Заключение

Web Socket - это протокол низкого уровня. Все, включая простой шаблон дизайна запроса / ответа, как создавать / обновлять / удалять необходимые ресурсы, коды состояния и т. Д., Должно быть построено поверх него. Все они хорошо определены для HTTP.

Web Socket - это протокол с отслеживанием состояния, тогда как HTTP - протокол без отслеживания состояния. Соединения через веб-сокеты могут масштабироваться вертикально на одном сервере, тогда как HTTP может масштабироваться горизонтально. Есть некоторые проприетарные решения для горизонтального масштабирования Web Socket, но они не основаны на стандартах. HTTP имеет много других полезных свойств, таких как кеширование, маршрутизация и мультиплексирование. Все это необходимо определить поверх Web Socket.

Следующий программный код описывает работу приложения чата с использованием протокола JavaScript и Web Socket.

<!DOCTYPE html>
<html lang = "en">

   <head>
      <meta charset = utf-8>
      <title>HTML5 Chat</title>
		
      <body>
		
         <section id = "wrapper">
			
            <header>
               <h1>HTML5 Chat</h1>
            </header>
				
            <style>
               #chat { width: 97%; }
               .message { font-weight: bold; }
               .message:before { content: ' '; color: #bbb; font-size: 14px; }
					
               #log {
                  overflow: auto;
                  max-height: 300px;
                  list-style: none;
                  padding: 0;
               }
					
               #log li {
                  border-top: 1px solid #ccc;
                  margin: 0;
                  padding: 10px 0;
               }
					
               body {
                  font: normal 16px/20px "Helvetica Neue", Helvetica, sans-serif;
                  background: rgb(237, 237, 236);
                  margin: 0;
                  margin-top: 40px;
                  padding: 0;
               }
					
               section, header {
                  display: block;
               }
					
               #wrapper {
                  width: 600px;
                  margin: 0 auto;
                  background: #fff;
                  border-radius: 10px;
                  border-top: 1px solid #fff;
                  padding-bottom: 16px;
               }
					
               h1 {
                  padding-top: 10px;
               }
					
               h2 {
                  font-size: 100%;
                  font-style: italic;
               }
					
               header, article > * {
                  margin: 20px;
               }
					
               #status {
                  padding: 5px;
                  color: #fff;
                  background: #ccc;
               }
					
               #status.fail {
                  background: #c00;
               }
					
               #status.success {
                  background: #0c0;
               }
					
               #status.offline {
                  background: #c00;
               }
					
               #status.online {
                  background: #0c0;
               }
					
               #html5badge {
                  margin-left: -30px;
                  border: 0;
               }
					
               #html5badge img {
                  border: 0;
               }
            </style>
				
            <article>
				
               <form onsubmit = "addMessage(); return false;">
                  <input type = "text" id = "chat" placeholder = "type and press 
                  enter to chat" />
               </form>
					
               <p id = "status">Not connected</p>
               <p>Users connected: <span id = "connected">0
                  </span></p>
               <ul id = "log"></ul>
					
            </article>
				
            <script>
               connected = document.getElementById("connected");
               log = document.getElementById("log");
               chat = document.getElementById("chat");
               form = chat.form;
               state = document.getElementById("status");
					
               if (window.WebSocket === undefined) {
                  state.innerHTML = "sockets not supported";
                  state.className = "fail";
               }else {
                  if (typeof String.prototype.startsWith != "function") {
                     String.prototype.startsWith = function (str) {
                        return this.indexOf(str) == 0;
                     };
                  }
						
                  window.addEventListener("load", onLoad, false);
               }
					
               function onLoad() {
                  var wsUri = "ws://127.0.0.1:7777";
                  websocket = new WebSocket(wsUri);
                  websocket.onopen = function(evt) { onOpen(evt) };
                  websocket.onclose = function(evt) { onClose(evt) };
                  websocket.onmessage = function(evt) { onMessage(evt) };
                  websocket.onerror = function(evt) { onError(evt) };
               }
					
               function onOpen(evt) {
                  state.className = "success";
                  state.innerHTML = "Connected to server";
               }
					
               function onClose(evt) {
                  state.className = "fail";
                  state.innerHTML = "Not connected";
                  connected.innerHTML = "0";
               }
					
               function onMessage(evt) {
                  // There are two types of messages:
                  // 1. a chat participant message itself
                  // 2. a message with a number of connected chat participants
                  var message = evt.data;
						
                  if (message.startsWith("log:")) {
                     message = message.slice("log:".length);
                     log.innerHTML = '<li class = "message">' + 
                        message + "</li>" + log.innerHTML;
                  }else if (message.startsWith("connected:")) {
                     message = message.slice("connected:".length);
                     connected.innerHTML = message;
                  }
               }
					
               function onError(evt) {
                  state.className = "fail";
                  state.innerHTML = "Communication error";
               }
					
               function addMessage() {
                  var message = chat.value;
                  chat.value = "";
                  websocket.send(message);
               }
					
            </script>
				
         </section>
			
      </body>
		
   </head>	
	
</html>

Ключевые функции и результаты работы приложения чата обсуждаются ниже -

Для проверки откройте два окна с поддержкой веб-сокетов, введите сообщение выше и нажмите клавишу возврата. Это позволит использовать функцию чата.

Если соединение не установлено, выход доступен, как показано ниже.

Результат успешного общения в чате показан ниже.

Сеть в значительной степени построена на парадигме запроса / ответа HTTP. Клиент загружает веб-страницу, а затем ничего не происходит, пока пользователь не перейдет на следующую страницу. Примерно в 2005 году AJAX начал делать Интернет более динамичным. Тем не менее, вся связь HTTP управляется клиентом, что требует взаимодействия с пользователем или периодического опроса для загрузки новых данных с сервера.

Технологии, которые позволяют серверу отправлять данные клиенту в тот момент, когда он знает, что новые данные доступны, существуют уже довольно давно. Они носят такие имена, как"Push" или же “Comet”.

С участием long polling, клиент открывает HTTP-соединение с сервером, которое остается открытым до отправки ответа. Каждый раз, когда на сервере появляются новые данные, он отправляет ответ. Длинный опрос и другие методы работают достаточно хорошо. Однако у всех них есть одна проблема: они несут накладные расходы HTTP, что не делает их подходящими для приложений с малой задержкой. Например, многопользовательский шутер в браузере или любая другая онлайн-игра с компонентом реального времени.

Вывод сокетов в Интернет

Спецификация веб-сокетов определяет 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. Одновременное поддержание большого количества открытых соединений требует архитектуры, которая обеспечивает высокий уровень параллелизма при низких затратах на производительность.

Протокол должен быть разработан из соображений безопасности. WebSocket - это совершенно новый протокол, и не все веб-браузеры реализуют его правильно. Например, некоторые из них по-прежнему позволяют сочетать HTTP и WS, хотя спецификация подразумевает обратное. В этой главе мы обсудим несколько распространенных атак на систему безопасности, о которых должен знать пользователь.

Отказ в обслуживании

Атаки типа «отказ в обслуживании» (DoS) пытаются сделать машину или сетевой ресурс недоступными для пользователей, которые их запрашивают. Предположим, кто-то делает бесконечное количество запросов к веб-серверу с небольшими временными интервалами или без них. Сервер не может обрабатывать каждое соединение и либо перестанет отвечать, либо будет продолжать отвечать слишком медленно. Это можно назвать атакой отказа в обслуживании.

Отказ в обслуживании очень разочаровывает конечных пользователей, которые не могут даже загрузить веб-страницу.

DoS-атака может применяться даже к одноранговой связи, вынуждая клиентов сети P2P одновременно подключаться к веб-серверу жертвы.

Человек посередине

Разберемся в этом на примере.

Предположим, что человек A болтает со своим другом Bчерез IM-клиент. Некоторые третьи лица хотят просматривать сообщения, которыми вы обмениваетесь. Таким образом, он устанавливает независимые связи с обоими людьми. Он также отправляет сообщения человекуA и его друг B, как невидимое промежуточное звено в вашем общении. Это известно как атака «человек посередине».

Атака типа «человек посередине» проще для незашифрованных соединений, поскольку злоумышленник может читать пакеты напрямую. Когда соединение зашифровано, информация должна быть расшифрована злоумышленником, что может быть слишком сложно.

С технической точки зрения злоумышленник перехватывает обмен сообщениями с открытым ключом и отправляет сообщение, заменяя запрошенный ключ своим собственным. Очевидно, что надежной стратегией, которая затруднит работу злоумышленника, является использование SSH с WebSockets.

В основном при обмене критически важными данными предпочитайте защищенное соединение WSS вместо незашифрованного WS.

XSS

Межсайтовый скриптинг (XSS) - это уязвимость, которая позволяет злоумышленникам внедрять клиентские скрипты в веб-страницы или приложения. Злоумышленник может отправить код HTML или Javascript с помощью концентраторов ваших приложений и позволить этому коду выполняться на машинах клиентов.

Собственные механизмы защиты WebSocket

По умолчанию протокол WebSocket разработан для обеспечения безопасности. В реальном мире пользователь может столкнуться с различными проблемами, которые могут возникнуть из-за плохой реализации браузера. Со временем поставщики браузеров немедленно исправляют любые проблемы.

Дополнительный уровень безопасности добавляется при использовании безопасного соединения WebSocket через SSH (или TLS).

В мире WebSocket основное внимание уделяется производительности безопасного соединения. Хотя сверху еще есть дополнительный уровень TLS, сам протокол содержит оптимизацию для такого использования, кроме того, WSS работает более гладко через прокси.

Маскировка клиент-сервер

Каждое сообщение, передаваемое между сервером WebSocket и клиентом WebSocket, содержит определенный ключ, называемый маскирующим ключом, который позволяет любым WebSocket-совместимым посредникам разоблачать и проверять сообщение. Если посредник не совместим с WebSocket, это не повлияет на сообщение. Браузер, реализующий протокол WebSocket, обрабатывает маскирование.

Панель инструментов безопасности

Наконец, могут быть представлены полезные инструменты для исследования потока информации между вашими клиентами WebSocket и сервером, анализа данных, которыми обмениваются, и выявления возможных рисков.

Инструменты разработчика браузера

Chrome, Firefox и Opera - отличные браузеры с точки зрения поддержки разработчиков. Их встроенные инструменты помогают нам определять практически любой аспект взаимодействия и ресурсов на стороне клиента. Это играет большую роль в целях безопасности.

WebSocket, как следует из названия, использует Интернет. Интернет обычно переплетается со страницами браузера, потому что это основное средство отображения данных в Интернете. Однако программы, не являющиеся браузерами, также используют передачу данных в режиме онлайн.

Выпуск iPhone (первоначально) и iPad (позже) представил совершенно новый мир веб-взаимодействия без обязательного использования веб-браузера. Вместо этого новые смартфоны и планшеты использовали мощь собственных приложений, чтобы предложить уникальный пользовательский интерфейс.

Почему важны мобильные устройства?

В настоящее время существует миллиард активных смартфонов. То есть миллионы потенциальных клиентов для ваших приложений. Эти люди используют свой мобильный телефон для выполнения повседневных задач, работы в Интернете, общения или покупок.

Смартфоны стали синонимом приложений. В настоящее время существует приложение для любого использования, которое может придумать пользователь. Большинство приложений подключаются к Интернету для получения данных, совершения транзакций, сбора новостей и т. Д.

Было бы здорово использовать существующие знания WebSocket и разработать клиент WebSocket, изначально работающий на смартфоне или планшете.

Нативное мобильное приложение против мобильного веб-сайта

Что ж, это частый конфликт, и, как правило, ответ зависит от потребностей целевой аудитории. Если пользователь знаком с современными тенденциями дизайна, создание адаптивного и удобного для мобильных устройств веб-сайта теперь просто необходимо. Однако конечный пользователь должен быть уверен, что контент, который действительно важен, в равной степени доступен через смартфон, как и через классический настольный браузер.

Определенно, веб-приложение WebSocket будет работать в любом браузере, совместимом с HTML5, включая мобильные браузеры, такие как Safari для iOS и Chrome для мобильных устройств. Поэтому проблем с совместимостью со смартфонами не стоит беспокоиться.

Предпосылки

Для разработки приложения для смартфона требуется установка средств разработки и SDK.

WebSockets может выступать в качестве универсального концентратора для передачи сообщений между подключенными мобильными и планшетными клиентами. Мы можем реализовать собственное приложение iOS, которое взаимодействует с сервером WebSocket так же, как клиент HTML5 JavaScript.