Web Socket API и Server-Sent Events

Web Socket API

Последнее обновление: 09.11.2023

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

Для создания подключения через Web Soket API применяется конструктор WebSocket(), в который передается адрес подключения.

const connection = new WebSocket("ws://example.com/test");

Управление жизненным циклом соединения

Для управления подключением для WebSocket определено три события:

  • open: вызывается при успешном открытии подключения. Обработчик можно установить с помощью свойства onopen

  • error: вызывается при возникновении ошибки при подключении. Обработчик устанавливается через свойство onerror. В функцию обработчика передается информация об ошибке

  • close: вызывается при закрытии подключения. Обработчик устанавливается с помощью свойства onclose

Пример обработки событий:

const connection = new WebSocket("ws://example.com/test");
// если соединение успешно установлено
connection.onopen = (event) => {  
    console.log("Connection opened");
};
// если возникла ошибка
connection.onerror = (error) => {
    console.log(`WebSocket Error: ${error}`);
};
// если соединение закрыто
connection.onclose = (event) => {
    console.log("Connection closed");
};

Отправка данных на сервер

Для отправки данных на сервер применяется метод send() объекта WebSocket. В качестве параметра в метод можно передать строки, бинарные данные (BLOB), объекты ArrayBuffer, типизированные массивы. Естественно отправка данных возможна только после успешной установки соединения. Например, отправка строки:

// если установлено соединение, отправляем строку
connection.onopen = (event) => {  
    connection.send("Hello METANIT.COM");
};

Или к примеру, если мы хотим отправить объект в формате JSON, то в начале его надо преобразовать в данный формат:

const data = {  message: "Hello"};
// отправляем объект в формате json
connection.send(JSON.stringify(data));

Прием данных

Когда приходят данные с сервера, у объекта WebSocket срабатывает событие message, для установки обработчика которого можно использовать свойство onmessage.

В обработчик события message передается объект типа MessageEvent. Этот объект предоставляет ряд свойств, которые позволяют извлечь данные ответа сервера:

  • data: возвращает полученные данные

  • origin: хранит адрес отправителя

  • lastEventId: хранит уникальный идентификатор события в виде строки.

  • source: возвращает объект MessageEventSource, который может быть объектом WindowProxy, MessagePort или ServiceWorker и который представляет отправителя полученных данных.

  • ports: возвращает массив объектов MessagePort, которые хранят использованные для отправки порты

Ключевое свойство тут, конечно, data, которое представляет полученные данные. Оно может представлять строку или бинарные данные. Если присланы бинарные данные, то свойство data может представлять тип ArrayBuffer, либо Blob. Пример получения данных:

connection.onmessage = (event) =>{ 
    console.log(event.data);
};

Если клиент получает бинарные данные, то с помощью свойства binaryType объекта WebSocket можно указать, какого именно типа мы хотим данные с помощью значений "blob" (для получения данных в виде объекта Blob) и "arraybuffer" (для получения данных в виде ArrayBuffer). Например:

const connection = new WebSocket("ws://example.com/test");
connection.binaryType = "arraybuffer";

Закрытие подключения

Для закрытия соединения у объекта WebSocket вызывается метод close():

connection.close();

Взаимодействие с сервером

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

Мы могли бы написать весь код работы с WebSocket с нуля, но это не самая простая задача, и для демонстрации мы будем использовать имеющуюся специальную библиотеку - ws. Так, создадим файл server.js и определим в нем следующий код:

const WebSocket = require("ws");
const server = new WebSocket.Server({port: 9000});

server.on("connection", onConnect);

// обработчик подключения клиента
// параметр - подключенный клиент
function onConnect(client) {
  console.log("Connection opened");
  
    // обрабатываем входящие сообщения от клиента
    client.on("message", function(message) {
        console.log("Client message:", message.toString());    // для диагностики сообщения клиента на консоль
        
        client.send("Hello Client");    // отправка сообщения клиенту
    });
    // закрытие подключения
    client.on("close", function() {
        console.log("Connection closed");
    });
}

console.log("Сервер запущен на 9000 порту");

Для создания сервера WebSocket вызываем функцию Server из библиотеки ws:

const WebSocket = require("ws");
const server = new WebSocket.Server({port: 9000});

Далее с помощью метода on() добавляем серверу для события "connection", которое срабатывает при подключении нового клиента, обработчик - функцию onConnect.

server.on("connection", onConnect);

В обработчик события в качестве параметра передается объект, через который моно взамодействовать с клиентом:

function onConnect(client) {

В этом обработчике устанавливаем для подключенного клиента событие "message", которое срабатывает, когда клинет присылает на сервер данные:

client.on("message", function(message) {
    console.log("Client message:", message.toString());    // для диагностики сообщения клиента на консоль
    client.send("Hello Client");    // отправка сообщения клиенту
  });

В функцию-обработчик события "message" передаются присланные от клиента данные (здесь параметр message). Внутри функции-обработчика выводим эти данные на консоль и с помощью метода send() посылаем клиенту некоторый ответ. Таким образом сервер получит от клиента данные и пошлет ему обратно ответ.

Также устанавливается обработчик события "close" для обработчик закрытия подключения.

Проблема с библиотекой "ws" заключается в том, что это не встроенная в Node.js библиотека, а сторонняя библиотека. Поэтому нам ее надо установить. Для этого перейдем в консоли к папке, где находится файл server.js, и далее в консоли выполним следующую команду

npm install ws

Эта команда установить библиотеку ws.

Теперь определим код клиента. Пусть это будет следующая страница index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>METANIT.COM</title>
</head>
<body>
<script>
const connection = new WebSocket("ws://localhost:9000");
// если соединение успешно установлено
connection.onopen = (event) => {  
    console.log("Connection opened");
    connection.send("Hello Server");
};
// если возникла ошибка
connection.onerror = (error) => {
    console.log(`WebSocket Error: ${error}`);
};
// если соединение закрыто
connection.onclose = (event) => {
    console.log("Connection closed");
};
// получаем ответ сервера
connection.onmessage = (event) =>{ 
    console.log("Server response:", event.data);
};
</script>
</body>
</html>

В целом код работы с WebSocket был рассмотрен ранее. Отмечу основные моменты. При открытии подключения отправляем на сервер строку "Hello Server"

connection.send("Hello Server");

А при получении ответа сервера выводим полученные данные на консоль:

connection.onmessage = (event) =>{ 
    console.log(event.data);
};

Перейдем в консоли к папке, где располагается файл сервера - server.js и выполним в консоли команду

node server.js

Эта команда запустит сервер. И после этого кинем нашу веб-страницу index.html в браузер и посмотрим на его консольный вывод. В итоге консольный вывод сервера будет следующим:

C:\app> node server.js
Сервер запущен на 9000 порту
Connection opened
Client message: Hello Server

А консольный вывод клиента - веб-страницы index.html следующим:

Connection opened
Server response: Hello Client
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850