Знание сетевых протоколов http websocket

WebSocket: разбираем как работает

HTTP — Протокол для передачи гипертесктовых данных (Hyper Text Transfer Protocol), который используется повсеместно. HTTP используется в клиент-серверной архитектуре, там всю работу можно показать с помощью одной диаграммы:

Особенности HTTP

  • HTTP не поддерживает соединение, после того, как отдает ответ на запрос.
  • HTTP обязует клиентов заранее оговаривать действие, которое клиент хочет
    сделать в заголовке (HTTP Headers) — GET, POST, PUT, DELETE
  • Мы отправляем заголовок что хотим сделать каждый раз, как обраемся к серверу

Существует большое количество сайтов, с помощью которых вы можете посмотреть как работает HTTP, давайте возьмем забавный сайт с REST API по мультивселенной Рик и Морти — https://rickandmortyapi.com/documentation.

Вы можете отправить запрос с помощью Postman или обычного cURL, я буду использовать второй😊 Давайте возьмем информацию о персонаже (Рике) и посмотрим что нам пришлёт сервер, для этого используем данную ссылку: https://rickandmortyapi.com/api/character/1

# Отправляем запрос с помощью cURL и парсим пришедший ответ с помощью JQ curl https://rickandmortyapi.com/api/character/1 | jq

После данной команды мы получим следующий ответ. Как мы видим мы просто отправили запрос на получение информации с сервера (GET), сервер отдал нам информацию и после этого мы разрываем соединение. После того как мы получим ответ мы ничего не знаем о сервере👀

Нам пришли данные в формате JSON как ответ от сервера

Вторая ступень: AJAX

AJAX — асинхронные запросы с помощью JavaScript (Asynchonous JavaScript and XML). AJAX преследует все те же цели, что и HTTP, только делает это уже асинхронно. Если ранее нужно было для каждого запроса прописывать свой URL и перезагружать страницу, то теперь можно просто использовать AJAX и он сам будет отправлять нужные URL серверу и получать данные.

Особенности AJAX

  • Все ещё обычный запрос, который не поддерживает соединение, после того, как отдает ответ на запрос.
  • Все ещё заранее оговариваем действие, которое клиент хочет сделать в заголовке (HTTP Headers) — GET, POST, PUT, DELETE
  • Мы отправляем заголовок что хотим сделать каждый раз, как обраемся к серверу
  • Теперь мы делаем это асинхронно благодаря JavaScript
Читайте также:  Назначение всех видов компьютерных сетей определяется двумя функциями

Самым простым примером AJAX является следующая реализация:

// Реализация на NodeJS ^17.5 // Будет работать в браузерах ~если вы не на Internet Explorer 8~ /** * Метод для того чтобы показать вывод AJAX-запроса * @param url - ссылка, которую будем подтягивать * @returns */ function showAJAXResponse(url) < // Выполняем запрос на сервер fetch(url) .then(res =>res.json()) // Формируем JSON .then(data => console.log(data)); // Выводим > // Отправляем AJAX запрос😊 showAJAXResponse('https://rickandmortyapi.com/api/character/1');

Вот что мы получим в итоге:

Мы можем выполнить множество таких запросов (серьзено, хоть 1000, если сервер позволит), как мы можем увидить мы ничего не перезагружаем (нам даже перезагружать нечего😅, мы делаем все на бэк-энде Node.js)

Как мы можем увидеть, мы все ещё не держим связь с сервером. Мы отправили запрос, получили ответ и все😳 Что дальше происходит с сервером нам неизвестно.

Третья ступень: WS или WebSocket

WebSocket — протокол для общения между клиентом и сервером, предоставляющий двухсторонне общение сверх протокола TCP.

Мы подключаем WS один раз, а затем сервер может отдавать нам ответы тогда, когда посчитает нужным:

Как это работает?

Первое что мы делаем — отправляем обычный TCP-запрос на сервер, мы говорим, что хотим подключиться к серверу и ждём от него ответа. Такой процесс называется “рукопожатие” (Handshake), он используется повсеместно, например когда вы подключаетесь к роутеру ваш телефон отправляем запрос роутеру с ключами, роутер отвечает ОК и вы успешно подключаетесь.

Затем происходит обмен данными: допустим один из множества клиентов отправил HTTP-запрос серверу и нужно отдать ответ не только одному клиенту, а целой сети! Сервер в таком случае отдаст обычный ответ отправителю запроса, а всем другим пришлёт пакеты по WebSocket-соединению с полезными данными.

Читайте также:  Компьютерные сети все про них

Разберем более подробно на примере. Вы — клиент, отправляете запрос серверу на подключение. Запрос и ответ будут выглядеть примерно так👁:

// Отправляем запрос серверу по ссылке example.com/connect-to-ws // Вот что примерно мы пришлём: GET /connect-to-ws HTTP/1.1 Host: example.com:8000 Upgrade: websocket Connection: Upgrade Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== Sec-WebSocket-Version: 13 // А вот что нам на такой запрос ответит сервер при успешном рукопожатии: HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

Как мы видим сервер ответил не кодом 200 (успешное завершение запроса), а 101 — переключение протоколов. Это происходит потому, что мы отправили HTTP запрос, а хотим получить не только HTTP-ответ, а ещё и другие ответы по WS, сервер как бы предупреждает клиент, что будет присылать ответы множество раз🔙

А как сервер узнает, что мы до сих пор подключены?😅

Ответ на данный вопрос достаточно легкий — сервер и клиент играют в пинг-понг😁🏓😳

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

Полезно знать, что все ответы от сервера по WS игнорируются клиентом и сервером, до того как случится рукопожатие🤝

Почему соединение называется двухсторонним (дуплексным), а ответы мы получаем только от сервера?

На самом деле мы не только получаем ответы от сервера, а ещё и можем в двухстороннем порядке отправлять через WS запросы!😳

Чтобы лучше понять, давайте рассмотрим лёгенький и полностью задокументированный код на JavaScript:

 // Создаем WS-объект, с помощьюю него будем рулить потоками // (отправка, принятие запросов) const myWS = new WebSocket(url, protocols); // До того как сервер и клиент совершат рукопожатие // статус у WS-клиента будет CONNECTING console.log(myWS.readyState); // CONNECTING // После того как рукопожатие (Handshake) пройдет успешно // readyState будет OPEN console.log(myWS.readyState); // OPEN 

После того как мы открыли соединение по WS мы сразу же можем отправить сообщение серверу:

/* Не забываем, что мы можем отправить сообщение серверу только если соединение открыто Поместим все общение с сервером внутрь ивента onopen, именно он срабатывает, когда соединение открыто */ myWS.onopen = function (event) < // Отправляем сообщение по WS myWS.send('Привет, сервер!'); >

Сервер получит данный запрос и возможно захочет ответить, но мы не сможем прочитать ответ! Почему? Да просто потому что у нас нет слушателя на событие получения сообщения от сервера😊 Сделаем же его:

// Вешаем слушатель на принятие сообщений myWS.onmessage = (event) => < // Делаем с данными все что захотим, но я их просто выведу😊 console.log(event.data); >

Закрытие соединения

Для закрытия соединения мы должны отправить запрос серверу, а он по истечению таймаута тоже должен отправить ответ на подтверждение закрытия. В JavaScript это делается одним методом😌

// Закрываем соединение myWS.close(); // Ну и естественно слушаем событие onclose, чтобы выполнить какие-то действия myWS.onclose = (event) => < // . >;

Особенности WS

  • Поддерживает двухсторонее соединение в реальном времени
  • Отправляет заголовок только один раз
Читайте также:  Оптимизация сетевой модели курсовая

Дебаггинг WS

Отлаживать WS-соединение совсем несложно😊 Рассмотрим пример отладки WS на Google Chrome🌎, перейдем на данный сайт: https://websocketstest.com/

Откроем DevTools, выберем вкладку Networks и перейдем в таб WS:

Как мы видим ответ от сервера действительно 101 Switching Protocols, однако как нам увидеть данные, которые приходят по WS, вкладки Reponse же нет🤔

Вкладки Response нет, зато появилась новая — Messages. Открываем её и видим там примерно следующее:

Красной стрелкой вниз показаны пакеты, которые пришли нам (пусть вас не вводит в заблуждение красная стрелка, это не упавшие, а пришедшие пакеты), отправленные пакеты в свою очередь будут показаны зелёной стрелкой, которая стремится вверх⬆

Вот и все😊 Если вам было интересно читать статью и вы хотите больше такого контента, то можете перейти в телеграм-канал и подписаться, там много интересного материала✨ Был рад поделиться информацией, увидимся ещё не раз👋

Источник

Оцените статью
Adblock
detector