Русский
Русский
English
Статистика
Реклама

Как использовать Websocket на примере простого Express API?

Краткое описание технологии

Websocket это протокол связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.
Для установления соединения WebSocket клиент и сервер используют протокол, похожий на HTTP. Клиент формирует особый HTTP-запрос, на который сервер отвечает определенным образом.

Примечания.
Несмотря на похожесть новых запросов и ответов на запросы и ответы протокола HTTP, они таковыми не являются. Например, в запросе есть тело, но в заголовках поле Content-Length отсутствует (что нарушает соглашения HTTP). Подробнее об этом можно прочитать в Википедии.
Одним из главных преимуществ технологии это ее простота. На клиенте и сервере есть всего 4 события для обработки:

  1. connection
  2. error
  3. message
  4. close

Почему Websocket?


Кроме ws существуют еще два способа непрерывной передачи данных: Server-Sent Events (SSE) и Long Polling.
Приведем сравнения механизмов непрерывной связи сервера и клиента, а также сделаем выводы, почему стоит (или не стоит) использовать вебсокет.
Websocket sse long pooling
протокол websocket (ws, или wss) HTTP(S) HTTP(S)
скорость высокая низкая низкая
направленность потоков данных двунаправленная однонаправленная двунаправленная
дополнительно передача бинарных данных,
отсутствует поддержка некоторых старых браузеров
автоматическое переподключение при обрыве соединения

Одним из главных преимуществ технологии ws это скорость передачи данных. SSE и LP используют протокол HTTP(S) и работают примерно так:

  1. Делаем запрос на изменения;
  2. Если изменения на сервере появились, то сервер их отправляет;
  3. Когда клиент получает изменения, клиент делает новый запрос.

Выводы:
  1. Вебсокет не требует от клиента постоянно запрашивать изменения и именно поэтому он быстрее.
  2. Вебсокет позволяет передавать бинарные данные, что не позволяет протокол HTTP(S).
  3. Вебсокет не нужно использовать, если проект требует совместимость со старыми версиями браузеров. Читать о совместимости с браузерами

Пример работы простейшего api.


const http = require("http");const express = require( "express");const WebSocket = require( "ws");const app = express();const server = http.createServer(app);const webSocketServer = new WebSocket.Server({ server });webSocketServer.on('connection', ws => {   ws.on('message', m => {webSocketServer.clients.forEach(client => client.send(m));   });   ws.on("error", e => ws.send(e));   ws.send('Hi there, I am a WebSocket server');});server.listen(8999, () => console.log("Server started"))

Что здесь происходит?
Чтобы создать сервер поддерживающий ws, мы создаем обычный http сервер, а потом привязываем к нему при создании websocket сервер.

Функция on помогает управлять событиями websocket. Самым примечательным является событие message, так что рассмотрим его подробнее.

Здесь функция получает параметр m сообщение, то есть то, что отправил пользователь. Таким образом мы можем отправить с клиента строку и обработать ее на сервере. В данном случае сервер просто пересылает это сообщение всем, кто подключен к серверу websocket. Массив clients объекта webSocketServer содержит все подключения к серверу. Объект ws в то же время хранит данные только об одном подключении.

Замечание.

Не стоит использовать такой подход в реальном приложении. Если описать api таким образом, то сервер не может отличить один запрос от другого. О том, как можно построить api на основе websocket будет написано далее.

Взаимодействие с сервером на клиенте будет выглядеть так:
export const wsConnection = new WebSocket("ws://localhost:8999");wsConnection.onopen = function() {    alert("Соединение установлено.");};wsConnection.onclose = function(event) {    if (event.wasClean) {        alert('Соединение закрыто чисто');    } else {        alert('Обрыв соединения'); // например, "убит" процесс сервера    }    alert('Код: ' + event.code + ' причина: ' + event.reason);};wsConnection.onerror = function(error) {    alert("Ошибка " + error.message);};export const wsSend = function(data) {// readyState - true, если есть подключение    if(!wsConnection.readyState){        setTimeout(function (){            wsSend(data);        },100);    } else {        wsConnection.send(data);    }};

API на основе Websocket


В отличие от REST API, где запросы распределены по разным url, Websocket API имеет только один url. Для того, чтобы построить полноценное API на основе вебсокетов, необходимо научить систему отличать один запрос от другого. Это можно реализовать следующим образом:

1) С клиента мы будем передавать запросы в виде строки-json, которую распарсим на сервере:
const sendMessage = (message) => conn.send(JSON.stringify({ event: "chat-message", payload: { userName, message }}));

2) На сервере мы распарсим строку и выделем в ней поле event тип запроса. Пропишем для каждого типа соответствующий ответ:
const dispatchEvent = (message, ws) => {   const json = JSON.parse(message);   switch (json.event) {       case "chat-message": webSocketServer.clients.forEach(client => client.send(message));       default: ws.send((new Error("Wrong query")).message);   }}

Таким образом мы можем отправлять разные запросы на сервер и обрабатывать ответ в зависимости от запроса.

Заключение


Если вам была дана задача сделать API и вы узнали, что поддержка старых браузеров заказчика не интересует, то API на основе WebSocket отличный выбор. Для вашего удобства мы подготовили код клиентской и серверной части по ссылке.
Источник: habr.com
К списку статей
Опубликовано: 24.08.2020 14:14:04
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Разработка веб-сайтов

Websocket

Express

Nodejs

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru