Урок 7. Создание чата на NodeJS, SocketIO и VueJS. Подключение пользователя

WebSocket

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/websocket.

Протокол WebSocket (стандарт RFC 6455) предназначен для решения любых задач и снятия ограничений обмена данными между браузером и сервером.

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

Пример браузерного кода

Для открытия соединения достаточно создать объект WebSocket , указав в нём специальный протокол ws .:

У объекта socket есть четыре колбэка: один при получении данных и три – при изменениях в состоянии соединения:

Для посылки данных используется метод socket.send(data) . Пересылать можно любые данные.

…Или файл, выбранный в форме:

Просто, не правда ли? Выбираем, что переслать, и socket.send() .

Для того, чтобы коммуникация была успешной, сервер должен поддерживать протокол WebSocket.

Чтобы лучше понимать происходящее – посмотрим, как он устроен.

Установление WebSocket-соединения

Протокол WebSocket работает над TCP.

Это означает, что при соединении браузер отправляет по HTTP специальные заголовки, спрашивая: «поддерживает ли сервер WebSocket?».

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

Установление соединения

Пример запроса от браузера при создании нового объекта new WebSocket(«ws://server.example.com/chat») :

GET, Host Стандартные HTTP-заголовки из URL запроса Upgrade, Connection Указывают, что браузер хочет перейти на websocket. Origin Протокол, домен и порт, откуда отправлен запрос. Sec-WebSocket-Key Случайный ключ, который генерируется браузером: 16 байт в кодировке Base64. Sec-WebSocket-Version Версия протокола. Текущая версия: 13.

Все заголовки, кроме GET и Host , браузер генерирует сам, без возможности вмешательства JavaScript.

Создать подобный XMLHttpRequest-запрос (подделать WebSocket ) невозможно, по одной простой причине: указанные выше заголовки запрещены к установке методом setRequestHeader .

Сервер может проанализировать эти заголовки и решить, разрешает ли он WebSocket с данного домена Origin .

Ответ сервера, если он понимает и разрешает WebSocket -подключение:

Здесь строка Sec-WebSocket-Accept представляет собой перекодированный по специальному алгоритму ключ Sec-WebSocket-Key . Браузер использует её для проверки, что ответ предназначается именно ему.

Затем данные передаются по специальному протоколу, структура которого («фреймы») изложена далее. И это уже совсем не HTTP.

Расширения и подпротоколы

Также возможны дополнительные заголовки Sec-WebSocket-Extensions и Sec-WebSocket-Protocol , описывающие расширения и подпротоколы (subprotocol), которые поддерживает данный клиент.

Посмотрим разницу между ними на двух примерах:

Заголовок Sec-WebSocket-Extensions: deflate-frame означает, что браузер поддерживает модификацию протокола, обеспечивающую сжатие данных.

Это говорит не о самих данных, а об улучшении способа их передачи. Браузер сам формирует этот заголовок.

Заголовок Sec-WebSocket-Protocol: soap, wamp говорит о том, что по WebSocket браузер собирается передавать не просто какие-то данные, а данные в протоколах SOAP или WAMP («The WebSocket Application Messaging Protocol»). Стандартные подпротоколы регистрируются в специальном каталоге IANA.

Этот заголовок браузер поставит, если указать второй необязательный параметр WebSocket :

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

В ответе выше сервер указывает, что поддерживает расширение deflate-frame , а из запрошенных подпротоколов – только SOAP.

Соединение WebSocket можно открывать как WS:// или как WSS:// . Протокол WSS представляет собой WebSocket над HTTPS.

Кроме большей безопасности, у WSS есть важное преимущество перед обычным WS – большая вероятность соединения.

Дело в том, что HTTPS шифрует трафик от клиента к серверу, а HTTP – нет.

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

А в случае с WSS весь трафик сразу кодируется и через прокси проходит уже в закодированном виде. Поэтому заголовки гарантированно пройдут, и общая вероятность соединения через WSS выше, чем через WS .

Формат данных

Полное описание протокола содержится в RFC 6455.

Здесь представлено частичное описание с комментариями самых важных его частей. Если вы хотите понять стандарт, то рекомендуется сначала прочитать это описание.

Описание фрейма

В протоколе WebSocket предусмотрены несколько видов пакетов («фреймов»).

Они делятся на два больших типа: фреймы с данными («data frames») и управляющие («control frames»), предназначенные для проверки связи (PING) и закрытия соединения.

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

Фрейм, согласно стандарту, выглядит так:

С виду – не очень понятно, во всяком случае, для большинства людей.

Позвольте пояснить: читать следует слева-направо, сверху-вниз, каждая горизонтальная полоска это 32 бита.

То есть, вот первые 32 бита:

Сначала идёт бит FIN (вертикальная надпись на рисунке), затем биты RSV1, RSV2, RSV3 (их смысл раскрыт ниже), затем «опкод», «МАСКА» и, наконец, «Длина тела», которая занимает 7 бит. Затем, если «Длина тела» равна 126 или 127, идёт «Расширенная длина тела», потом (на следующей строке, то есть после первых 32 бит) будет её продолжение, ключ маски, и потом данные.

А теперь – подробное описание частей фрейма, то есть как именно передаются сообщения:

Одно сообщение, если оно очень длинное (вызовом send можно передать хоть целый файл), может состоять из множества фреймов («быть фрагментированным»).

У всех фреймов, кроме последнего, этот фрагмент установлен в 0 , у последнего – в 1 .

Если сообщение состоит из одного-единственного фрейма, то FIN в нём равен 1 .

RSV1, RSV2, RSV3: 1 бит каждый

В обычном WebSocket равны 0 , предназначены для расширений протокола. Расширение может записать в эти биты свои значения.

Задаёт тип фрейма, который позволяет интерпретировать находящиеся в нём данные. Возможные значения:

  • 0x1 обозначает текстовый фрейм.
  • 0x2 обозначает двоичный фрейм.
  • 0x3-7 зарезервированы для будущих фреймов с данными.
  • 0x8 обозначает закрытие соединения этим фреймом.
  • 0x9 обозначает PING.
  • 0xA обозначает PONG.
  • 0xB-F зарезервированы для будущих управляющих фреймов.
  • 0x0 обозначает фрейм-продолжение для фрагментированного сообщения. Он интерпретируется, исходя из ближайшего предыдущего ненулевого типа.

Маска: 1 бит

Если этот бит установлен, то данные фрейма маскированы. Более подробно маску и маскирование мы рассмотрим далее.

Длина тела: 7 битов, 7+16 битов, или 7+64 битов

Если значение поле «Длина тела» лежит в интервале 0-125 , то оно обозначает длину тела (используется далее). Если 126 , то следующие 2 байта интерпретируются как 16-битное беззнаковое целое число, содержащее длину тела. Если 127 , то следующие 8 байт интерпретируются как 64-битное беззнаковое целое, содержащее длину.

Такая хитрая схема нужна, чтобы минимизировать накладные расходы. Для сообщений длиной 125 байт и меньше хранение длины потребует всего 7 битов, для бóльших (до 65536) – 7 битов + 2 байта, ну а для ещё бóльших – 7 битов и 8 байт. Этого хватит для хранения длины сообщения размером в гигабайт и более.

Ключ маски: 4 байта.

Если бит Маска установлен в 0, то этого поля нет. Если в 1 то эти байты содержат маску, которая налагается на тело (см. далее).

Данные фрейма (тело)

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

Примеры

Некоторые примеры сообщений:

Нефрагментированное текстовое сообщение Hello без маски:

В заголовке первый байт содержит FIN=1 и опкод=0x1 (получается 10000001 в двоичной системе, то есть 0x81 – в 16-ричной), далее идёт длина 0x5 , далее текст.

Фрагментированное текстовое сообщение Hello World из трёх частей, без маски, может выглядеть так:

  • У первого фрейма FIN=0 и текстовый опкод 0x1 .
  • У второго FIN=0 и опкод 0x0 . При фрагментации сообщения, у всех фреймов, кроме первого, опкод пустой (он один на всё сообщение).
  • У третьего, последнего фрейма FIN=1 .

А теперь посмотрим на все те замечательные возможности, которые даёт этот формат фрейма.

Фрагментация

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

Например, идёт поиск в базе данных и что-то уже найдено, а что-то ещё может быть позже.

  • У всех сообщений, кроме последнего, бит FIN=0 .
  • Опкод указывается только у первого, у остальных он должен быть равен 0x0 .

PING / PONG

В протокол встроена проверка связи при помощи управляющих фреймов типа PING и PONG.

Тот, кто хочет проверить соединение, отправляет фрейм PING с произвольным телом. Его получатель должен в разумное время ответить фреймом PONG с тем же телом.

Этот функционал встроен в браузерную реализацию, так что браузер ответит на PING сервера, но управлять им из JavaScript нельзя.

Иначе говоря, сервер всегда знает, жив ли посетитель или у него проблема с сетью.

Чистое закрытие

При закрытии соединения сторона, желающая это сделать (обе стороны в WebSocket равноправны) отправляет закрывающий фрейм (опкод 0x8 ), в теле которого указывает причину закрытия.

В браузерной реализации эта причина будет содержаться в свойстве reason события onclose .

Наличие такого фрейма позволяет отличить «чистое закрытие» от обрыва связи.

В браузерной реализации событие onclose при чистом закрытии имеет event.wasClean = true .

Коды закрытия

Коды закрытия вебсокета event.code , чтобы не путать их с HTTP-кодами, состоят из 4 цифр:

1000 Нормальное закрытие. 1001 Удалённая сторона «исчезла». Например, процесс сервера убит или браузер перешёл на другую страницу. 1002 Удалённая сторона завершила соединение в связи с ошибкой протокола. 1003 Удалённая сторона завершила соединение в связи с тем, что она получила данные, которые не может принять. Например, сторона, которая понимает только текстовые данные, может закрыть соединение с таким кодом, если приняла бинарное сообщение.

Атака «отравленный кэш»

В ранних реализациях WebSocket существовала уязвимость, называемая «отравленный кэш» (cache poisoning).

Топ-пост этого месяца:  Как узнать ключевые слова конкурентов бесплатные сервисы

Она позволяла атаковать кэширующие прокси-сервера, в частности, корпоративные.

Атака осуществлялась так:

Хакер заманивает доверчивого посетителя (далее Жертва) на свою страницу.

Страница открывает WebSocket -соединение на сайт хакера. Предполагается, что Жертва сидит через прокси. Собственно, на прокси и направлена эта атака.

Страница формирует специального вида WebSocket-запрос, который (и здесь самое главное!) ряд прокси серверов не понимают.

Они пропускают начальный запрос через себя (который содержит Connection: upgrade ) и думают, что далее идёт уже следующий HTTP-запрос.

…Но на самом деле там данные, идущие через вебсокет! И обе стороны вебсокета (страница и сервер) контролируются Хакером. Так что хакер может передать в них нечто похожее на GET-запрос к известному ресурсу, например http://code.jquery.com/jquery.js , а сервер ответит «якобы кодом jQuery» с кэширующими заголовками.

Прокси послушно проглотит этот ответ и закэширует «якобы jQuery».

В результате при загрузке последующих страниц любой пользователь, использующий тот же прокси, что и Жертва, получит вместо http://code.jquery.com/jquery.js хакерский код.

Поэтому эта атака и называется «отравленный кэш».

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

Поэтому придумали способ защиты – «маску».

Маска для защиты от атаки

Для того, чтобы защититься от атаки, и придумана маска.

Ключ маски – это случайное 32-битное значение, которое варьируется от пакета к пакету. Тело сообщения проходит через XOR ^ с маской, а получатель восстанавливает его повторным XOR с ней (можно легко доказать, что (x ^ a) ^ a == x ).

Маска служит двум целям:

  1. Она генерируется браузером. Поэтому теперь хакер не сможет управлять реальным содержанием тела сообщения. После накладывания маски оно превратится в бинарную мешанину.
  2. Получившийся пакет данных уже точно не может быть воспринят промежуточным прокси как HTTP-запрос.

Наложение маски требует дополнительных ресурсов, поэтому протокол WebSocket не требует её.

Если по этому протоколу связываются два клиента (не обязательно браузеры), доверяющие друг другу и посредникам, то можно поставить бит Маска в 0 , и тогда ключ маски не указывается.

Пример

Рассмотрим прототип чата на WebSocket и Node.JS.

HTML: посетитель отсылает сообщения из формы и принимает в div

Урок 7. Создание чата на NodeJS, SocketIO и VueJS. Подключение пользователя

Мы расскажем про разработку веб сервисов на платформе Socket.io . Для работы с чатом необходимо будет ввести имя, после чего пользователи смогут обмениваться сообщениями будучи в разных городах и даже странах.

Мы реализуем программу при помощи платформы Socket.io, а также Node JS и Express. Socket.IO — JavaScript-библиотека, выполняющая роль программы для обмена данными между клиентами и сервером. Все обновления происходят в режиме реального времени, что позволяет создавать функционал на подобии веб чата, онлайн игры или других мультиплеерных сервисов.

Благодаря сокетам мы можем отправлять данные на один сервер, а далее все клиенты (пользователи), подключенные к этому серверу, будут видеть всю информацию и взаимодействовать с ней. На основе Socket.IO можно создавать как небольшие чат программы, так и полноценные мультиплеерные игры, запускаемые через браузер.

Для начала разработки необходимо установить Node JS, а также настроить проект, добавив в него необходимые библиотеки.

Для установки Node перейдите на их официальный сайт и выполните установку программы на ваш компьютер.

Создайте папку и откройте её через командную строку или терминал. В командной строке пропишите команду npm init . У вас спросят различные настройки, введите их:

Далее выполните установку npm install express и npm install socket.io . Это два пакета, которые понадобятся для разработки программы.

Далее создайте два файла: index.js , а также index.html . Оба эти файла представлены ниже вместе с комментариями.

HTML код программы:

JavaScript код программы:

Для более подробного пояснения можете также посмотреть видео урок:

Урок 2. Создание чата на NodeJS, SocketIO и VueJS. Подключение SocketIO

Oynatıcı kontrollerini göster

  • katma 4 Haz 2020
  • Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут:
    В данном уроке вы узнаете, как включить поддержку сокетов в express сервере.

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

Урок 1. Создание чата на NodeJS, SocketIO и VueJS. Настройка express сервера

Tampilkan kontrol pemutar

  • Dipublikasikan tanggal 4 Jun 2020
  • Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/
    В данном уроке вы узнаете, как начать разработку чата на nodejs и фреймворке express.

В данном уроке вы узнаете, как создать сервер на express и в браузере отдавать index.html файл клиенту.
Также вы увидите базовую настройку рабочего окружения для NodeJS.

Komentar • 18

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

афигетить какое название и какой видос, да ты крут

Указал бы express еще в названии. интересовала чистая нода =ъ

Как сделать, чтобы имя пользователя отображалось по русски?

Подойдёт ли телефон для этого чата?

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

Топ-пост этого месяца:  Robots для сайта как его правильно составить.txt

Vladilen Minin Я про сам процесс разработки, можно ли разработать этот чат технологиями, которые доступны телефонам? (К примеру, кодить в Sololearn)

Здесь рассматриваются именно веб технологии, так что нативного мобильного чата конечно же не будет

Vladilen Minin Я имел ввиду именно разработку данного чата на телефоне

Айхас 47, да подойдёт. Только нужно будет сделать адаптивную вёрстку — немного подделать ту вёрстку, что дана в курсе

Хорошие лекции у автора. Лесс по ним учил. Не реклама, а констатация факта.

Ваня Иванов, спасибо за отзыв! Мы с командой стараемся работать над качеством

Урок 2. Создание чата на NodeJS, SocketIO и VueJS. Подключение SocketIO

Oynatıcı kontrollerini göster

  • katma 4 Haz 2020
  • Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут:
    В данном уроке вы узнаете, как включить поддержку сокетов в express сервере.

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

Создание чата на NodeJS, SocketIO и VueJS

Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/

В данном курсе мы разберем способ создать простой чат на платформе NodeJS.
Из основных технологий на сервере мы будем использовать SocketIO и фреймворк Express. На клиентской части мы будем использовать VueJS и библиотеку Materialize-css для создания Material Design.
В результате курса мы получим рабочий чат и разберем способ деплоя данного приложения на бесплатный облачный сервис Heroku, используя инструмент Heroku-CLI и систему контроля версий GIT для того, чтобы приложение было доступно удаленно на домене.

Создание чата на NodeJS, SocketIO и VueJS

Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/

В данном курсе мы разберем способ создать простой чат на платформе NodeJS.
Из основных технологий на сервере мы будем использовать SocketIO и фреймворк Express. На клиентской части мы будем использовать VueJS и библиотеку Materialize-css для создания Material Design.
В результате курса мы получим рабочий чат и разберем способ деплоя данного приложения на бесплатный облачный сервис Heroku, используя инструмент Heroku-CLI и систему контроля версий GIT для того, чтобы приложение было доступно удаленно на домене.

Урок 1. Создание чата на NodeJS, SocketIO и VueJS. Настройка express сервера

Tampilkan kontrol pemutar

  • Dipublikasikan tanggal 4 Jun 2020
  • Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/
    В данном уроке вы узнаете, как начать разработку чата на nodejs и фреймворке express.

В данном уроке вы узнаете, как создать сервер на express и в браузере отдавать index.html файл клиенту.
Также вы увидите базовую настройку рабочего окружения для NodeJS.

Komentar • 18

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

афигетить какое название и какой видос, да ты крут

Указал бы express еще в названии. интересовала чистая нода =ъ

Как сделать, чтобы имя пользователя отображалось по русски?

Подойдёт ли телефон для этого чата?

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

Vladilen Minin Я про сам процесс разработки, можно ли разработать этот чат технологиями, которые доступны телефонам? (К примеру, кодить в Sololearn)

Здесь рассматриваются именно веб технологии, так что нативного мобильного чата конечно же не будет

Vladilen Minin Я имел ввиду именно разработку данного чата на телефоне

Айхас 47, да подойдёт. Только нужно будет сделать адаптивную вёрстку — немного подделать ту вёрстку, что дана в курсе

Хорошие лекции у автора. Лесс по ним учил. Не реклама, а констатация факта.

Ваня Иванов, спасибо за отзыв! Мы с командой стараемся работать над качеством

Создание чата на NodeJS, SocketIO и VueJS

Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/

В данном курсе мы разберем способ создать простой чат на платформе NodeJS.
Из основных технологий на сервере мы будем использовать SocketIO и фреймворк Express. На клиентской части мы будем использовать VueJS и библиотеку Materialize-css для создания Material Design.
В результате курса мы получим рабочий чат и разберем способ деплоя данного приложения на бесплатный облачный сервис Heroku, используя инструмент Heroku-CLI и систему контроля версий GIT для того, чтобы приложение было доступно удаленно на домене.

Создание чата на NodeJS, SocketIO и VueJS

Полный Премиум курс «Создание чата на NodeJS, SocketIO и VueJS» смотрите тут: webformyself.com/category/premium/javascript-premium/chatnodejs-premium/

В данном курсе мы разберем способ создать простой чат на платформе NodeJS.
Из основных технологий на сервере мы будем использовать SocketIO и фреймворк Express. На клиентской части мы будем использовать VueJS и библиотеку Materialize-css для создания Material Design.
В результате курса мы получим рабочий чат и разберем способ деплоя данного приложения на бесплатный облачный сервис Heroku, используя инструмент Heroku-CLI и систему контроля версий GIT для того, чтобы приложение было доступно удаленно на домене.

Добавить комментарий