Чат для вашего сайта NodeJS + WebSockets


Содержание

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

Чат на WebSocket’ах

В статье описывается, как разработать и запустить простейший чат на вебсокетах.

Сервер

Существует много готовых продуктов для запуска websocket-сервера. Наш сервер мы запустим используя библиотеку Workerman, ключевое преимущество которой – это полное отсутствие зависимостей: скачал, запустил – работает. Также в Workerman имеется поддержка таймеров прямо из коробки, они нам пригодятся. И конечно же! Библиотека написана на PHP, а все любят PHP ;-)

Цукерберг рекомендует:  C++ - Ошибка в программе

Клиент

Для разработки приложения-клиента я выбрал фреймворк Qt только потому, что он мне нравится. Qt – кроссплатформенная библиотека (фреймворк), позволяющая создавать программы практически под любую платформу: Windows, Linux, Android, OS X, iOS и др. Разумеется, клиент для полученного сервера можно написать на чем угодно, хоть на HTML+JS, который будет работать прямо из браузера.

1. Настройка VDS-сервера

Сразу после приобретения VDS и установки операционной системы (выбрал свежую версию Ubuntu 18.04 на тарифе «Master») подключаемся к нему. На сервер можно зайти через консоль из панели управления VDS, но это не самый удобный вариант. Предпочтительнее подключаться по SSH.

Если разные способы подключения по SSH из Windows, например:
1. Воспользоваться программой Putty;
2. Воспользоваться терминалом Cygwin;
3. Воспользоваться терминалом Ubuntu из WSL (я выбрал этот способ).

В Linux намного проще, клиент для подключения по SSH, как правило, установлен во всех дистрибутивах по умолчанию, поэтому просто открываем терминал.

Независимо от выбранного способа, команда для подключения будет одна:

где – это IP-адрес вашего сервера, который можно найти в панели управления VDS (блок «Список используемых IP-адресов»).

Установка Workerman

Чтобы скачать Workerman, сначала устанавливаем composer:

Теперь скачиваем Workerman в папку /usr/local/workerman:

И создаём php-файл, в котором будем писать код сервера чата:

Далее открываем файл ChatWorker.php для редактирования. Это можно сделать разными способами. Самый хардкорный и олдскульный вариант — редактировать прямо в терминале, воспользовавшись консольными редакторами nano, mcedit, vim и др.

Если работаете в Linux, то из рабочего окружения KDE можно подключиться через файловый менеджер Dolphin по протоколу SFTP и открыть файл в любом редакторе или даже в IDE (например, в KDevelop).

Если работаете в Windows, то можете скачать Notepad++ с плагином NppFTP, либо что-то более продвинутое, вроде Sublime / Atom / Visual Studio Code, и так же подключиться по протоколу SFTP.

2. Сервер

Чат будет работать по такому принципу: сообщения между сервером и клиентом передаются в формате JSON с указанием, какое «действие» (action) выполняет это сообщение. Таким образом можно разделить сообщения на типы: служебные, публичные, приватные и т.д., и с лёгкостью дополнять различные типы служебной и иной сопутствующей информацией.


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

Наш простейший чат будет поддерживать следующие действия:

    авторизация пользователя

action = Authorized
При подключении пользователя к чату сервер предварительно проверяет свободность выбранного никнейма. Если никнейм занят, то приписываем к нему номер (2, 3, 4 и т.д.). Если никнейм свободен, то отправляем пользователю сообщение «Authorized», в котором передаются данные, с которыми он был авторизован в чате и список пользователей чата.
Дополнительно пользователь может выбрать цвет отображения своего имени и указать, к какому полу (М/Ж) относится.

оповещение всех пользователей о присоединении нового участника к чату

action = Connected
После авторизации нового пользователя сервер отправляет всем участникам сообщение «Connected», в котором передаются данные авторизованного пользователя.

оповещение всех пользователей при выходе участника из чата

action = Disconnected
При выходе пользователя из чата все участники оповещаются сообщением «Disconnected».

отправка сообщения в общий чат

action = PublicMessage
Если пользователь отправляет сообщение в чат без указания адресата, то такое сообщение определяется как «Публичное» и рассылается всем участникам.

отправка приватного сообщения

action = PrivateMessage
Если пользователь отправляет сообщение в чат с указанием адресата, то такое сообщение определяется как «Приватное» и отправляется только адресату.

проверка пользователей на потерю соединений

action = Ping
Сервер рассылает всем участникам служебное сообщение «Ping» с определённым интервалом и ожидает от каждого ответное сообщение «Pong».

оповещение пользователей о потере соединения участником

action = ConnectionLost
Если сервером несколько раз подряд не будет получено ответное на «Ping» сообщение от участника, то участник считается отключившимся, всем остальным участникам рассылается сообщение «ConnectionLost» с данными “отвалившегося” пользователя.

Инициализация WebSocket-сервера

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

Но обратите внимание: можно указать любой другой свободный порт, главное не забыть открыть его на VDS-сервере командой:

где – выбранный вами порт для чата.

Запускаем WebSocket-сервер командой:

Для проверки соединения и дальнейшей отладки можно воспользоваться плагином Simple WebSocket Client для браузера Google Chrome.

Окно плагина Simple WebSocket Client

В поле Server Location -> URL: вводим адрес сервера, начиная с названия протокола: ws:// и нажимаем кнопку Open.

При успешном подключении метка Status: CLOSED будет заменена на OPENED и разблокируется поле Request, которое в дальнейшем можно будет использовать для отправки тестовых запросов как от клиента. По сути, наш браузер уже является клиентом для сервера, просто не имеет визуального оформления и обработчиков сообщений.

Инициализировать сервер было легко, но надо ведь ещё обработать события!

Подключение и авторизация пользователя

Авторизация пользователя будет происходить во время подключения клиента к серверу с передачей параметров. Параметры подключения передаются в адресной строке как в обычном URL-адресе (QUERY STRING), а на сервере их можно прочитать из переменной $_GET.

Предполагается, что при подключении приложение-клиент должно передать все необходимые сведения о пользователе:
— отображаемое имя (ник): параметр userName;
— цвет ника: параметр userColor;
— пол: параметр gender.

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

При подключении клиента к websocket-серверу, вызывается функция Worker::onConnect, в которую передается указатель на созданный объект соединения TcpConnection.

После подключения обрабатываются все параметры подключения (а нас как раз и интересует то, с какими параметрами осуществлялось подключение) и затем вызывается функция установки соединения TcpConnection::onWebSocketConnect – в которой будет доступна обработанная переменная $_GET — отсюда будем извлекать сведения о подключившемся клиенте.

Обратите внимание!

Вызов функцииWorker::runAll() запускает цепь обработки событий Workerman. Код, написанный после вызова этой функции, не будет выполнен. Помните об этом при внесении дальнейших изменений.

Сохраним файл на сервере и перезапустим Workerman. Остановить предыдущий запуск можно клавишами CTRL+C, а затем снова запустить той же командой:

Обратите внимание!

Перезапускать WebSocket-сервер нужно после каждого внесения изменений в любой из php-скриптов вашего проекта.

Пробуем подключиться с передачей параметров: ws://:27800?userName=anonymous

И вот, наконец, мы добрались до Hello World!

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

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

Первое (Authorized) отправляется только подключившемуся пользователю, чтобы сообщить ему, с какими данными он был подключен.

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

Отключение пользователя

Когда клиент закрывает соединение с сервером, вызывается функция Worker::onClose, тут обработаем выход пользователя из чата:

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

Пинг пользователей

При вызове метода Worker::runAll запускаются все объявленные «работники» (их может быть несколько), а при их запуске вызывается функция Worker::onWorkerStart – здесь добавим код таймера для пинга пользователей.

Примечание

Протокол WebSocket имеет встроенную реализацию ping/pong из коробки, но мы напишем собственную, в которой сможем выполнять дополнительные действия. Однако клиент будет дополнительно оповещать сервер о наличии подключения, используя встроенную реализацию.

Обработка сообщений

И самое главное — обработка сообщений клиента, которые приходят с вызовом метода Worker::onMessage:

На этом с сервером закончили. Полный код файла ChatWorker.php доступен на GitHub: https://github.com/wxmaper/SimpleChat-server

После тестирования websocket-сервер можно запустить в режиме службы, для этого нужно добавить параметр -d:

Перезапуск выполняется командой restart:

3. Клиент

Примитивное приложение-клиент будет реализовано с использованием модуля QtWidgets и написано на C++. Сообщения будут отображаться в обычном текстовом поле в режиме readonly (привет любителям лампового IRC :-)).

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

Режим приватного чата активируется двойным кликом по имени в списке пользователей, а закрывается этот режим специальной кнопкой [x], которая по умолчанию скрыта.

Сообщения отправляются нажатием на кнопку Return (Enter) на клавиатуре.

Прототип окна чата

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

В рамках этой статьи рассмотрим лишь основные моменты.

Установка соединения с сервером

В проекте реализован метод W >

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


Обработка сообщений

Вся логика общения клиента с сервером реализована в слоте Widget::onTextMessageReceived – тут проверяется тип входящего сообщения (какое он имеет «действие») и вызываются соответствующие методы для его обработки.

Оповещение пользователя

Если кликнуть по имени пользователя, то имя вставляется в поле ввода сообщения и заворачивается в фигурные скобки: «<» и «>».

На сервере имеется паттерн обработки такого текста (функция $worker->onMessage), который заменяет фигурные скобки на теги « » и « », выделяя текст жирным шрифтом.

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

По такой же схеме можно реализовать полноценную поддержку markdown, вставку смайликов и картинок.

Расширяя функционал сервера и клиента можно также добавить:

  • поддержку чат-комнат и полноценных приватных диалогов;
  • сохранении истории сообщений в БД и её отправку при подключении или по запросу;
  • статусы пользователей («Работаю», «Отдыхаю», «Отошёл» и др.);
  • звуковые уведомления «Послать сигнал»;
  • редактирование и удаление сообщений;
  • цитирование сообщений других пользователей;
  • передачу файлов.

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

Создание чат-приложения в режиме реального времени с Vue.js, Socket.IO и Node.js

В статье я расскажу, как можно создать чат-приложение в режиме реального времени с помощью Vue.js, Node.js, Express и SOCKET.IO.

Вот скриншот того, что должно получиться:

PS: Я не специалист по фронтенду, так что не смейтесь над дизайном. Данный макет используется только в качестве примера.

Установка

Для работы нам понадобятся Node.js и NPM. Если у вас еще нет установленного Node.JS, то качайте его отсюда.

  • Вам потребуются базовые знания JavaScript.
  • Пригодятся небольшие знания по Vue.js (но это не принципиально).

Если все готово, то можно начинать.

Создайте директорию для приложения и откройте ее в любимом редакторе. Я пользуюсь Visual Studio Code.

Если хотите, можете работать в терминале.

Давайте инициализируем директорию через NPM.

Если вам предлагают ввести какую-то информацию, смело ее вводите или нажимайте Enter для настроек по умолчанию. Такая информация используется для настройки пакета .json файла.

Установка зависимостей

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

После установки всех зависимостей запустите

Так установятся все необходимые пакеты.

Фронтенд с Vue.js (разметка)

Интерфейс приложения мы сделаем в Vue.js. Его нужно установить в нашу директорию и добавить bootstrap 4.3.1.

Создадим файл index.html.

Для включения в проекты Vue.js и bootstrap скопируем CDN и добавим в раздел со скриптами файла index.html.

После успешной установки Vue и bootstrap перейдем к созданию разметки.

Для подключения Socket.IO сервера к клиенту добавим клиентские JavaScript библиотеки.

Это будет наш файл Vue и bootstrap (HTML) для фронтенда. Можете скопировать код целиком, чтобы не отставать.

Лучший способ научиться чему-то — повторять за другими.

Можно разграничить функционал, вынеся JavaScript-код из общей разметки. Это решать вам. Но я для удобства этого делать не буду.

Установка сервера

Создадим server.js. Внутри файла создадим и настроим Express-сервер для работы с Socket.IO.

Это базовая конфигурация, необходимая для установки Socket.IO в бэкенде.

Как работает Socket.IO

Socket.IO — это JavaScript-библиотека чата в режиме реального времени. Документацию можно почитать здесь (она не относится к тематике данной статьи). Я объясню лишь то, что нам потребуется для статьи.

Работа Socket.IO сводится к добавлению слушателей события для экземпляра http.Server. Именно этим мы сейчас и займемся.

Затем будем прослушивать событие о новом подключении.

Например, если пользователь посещает 1 27.0.0.1:3000, то сообщение об этом напечатается в консоли.

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

Socket.ON(): принимает в качестве параметров название события и обратный вызов. Прослушивает события, отправленные на сервер и с него. Обратный вызов нужен для получения данных, связанных с событием.

Socket.EMIT(): отправляет/посылает событие с данными или без них для прослушивания сокетов (включая себя).

Socket.Broadcast.Emit(): отправляет событие всем подключенным клиентам (кроме себя). Эти методы пригодятся для отправки событий с сервера через чат-приложение.

Настройка кода клиентской части

Откройте index.html. В нижней части файла добавьте следующий код в тег script.

Мы добавили var socket = io(); и создали новый экземпляр Vue. Далее внутри этого экземпляра прописали наш элемент как el: ‘#app’ и объявили наш объект данных с помощью пустых массивов и свойств.

Давайте перейдем к объекту methods . Мы видим метод Send() . Он хранит информацию о чате в массиве message и отправляет события чата на сервер с помощью флага Socket.emit() .

На серверной стороне мы получаем событие с флагом Socket.on() и через флаг Socket.broadcast.emit() пересылаем его другим подключенным клиентам.

В хуке Vue CREATED мы прослушиваем все события, отправленные сервером. Сюда же включено событие chat-message, которое мы пересылали с сервера ранее.

Через трансляцию событий сервер отправляет их всем подключенным клиентам, кроме самого отправителя.

Аналогия

Если пользователь А отправляет сообщение на сервер, а сервер ретранслирует его пользователям B, C, D, E и т.д., то это сообщение получат все пользователи, кроме А, поскольку он является отправителем.

Так что нет ничего страшного в том, что мы прослушиваем событие chat-message из объекта CREATED. Все равно мы, как отправители, не получим это сообщение с сервера.

Именно так все и происходит, когда пользователи выполняют какие-то действия в ChatApp.

После получения с сервера события из объекта CREATED , мы сохраняем его в массиве message с message type (указывает, что сообщение отправлено с сервера) и user (тот, кто отправил сообщение).

Подведем итог всему происходящему во фронтенде.

1. Хук Methods. Именно здесь в Vue.js вы создаете все методы/функции для компонента. И при каждом вызове метода в разметке/шаблоне Vue обращается к этому хуку.

У нас есть только два объявленных метода:

i. Send(). Этот метод вызывается, когда пользователь печатает сообщение и нажимает «Отправить». Он сохраняет сообщение в массиве message и отправляет события на сервер (см. выше).

ii. addUser(). Метод отправляет на сервер событие joined и устанавливает значение переменной ready как true, показывая, что пользователь успешно присоединился к чату.

2. Хук Created. Данный хук вызывается при загрузке компонента Vue.js. Это отличное место для прослушивания всех событий с сервера.

Мы прослушиваем 6 событий с сервера и отправляем 1 событие на сервер.

В коде выше видно, чем занимается каждое событие.

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

Еще он применяется для отметки о прочтении в разметках с используемыми директивами Vue.js. Вот полный файл index.html.

Заключение


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

Веб-заметки и Веб-подсказки

О WebSocket-ах на примере реализации чата мгновенных сообщений с помощью node.JS

Цель этой статьи — на простом примере ознакомится с новым, еще непривычным, подходом в организации взаимодействия веб-приложений с сервером. В качестве «Hello World»-приложения для этой технологии нам отлично послужит чат. В статье будет продемонстрирована реализация серверной и клиентской частей приложения, чтобы лучше понимать как они взаимодействуют.

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

Ну что же, приступим к созданию нашего чата. И первое, что нам предстоит реализовать — это сервер. Сервер мы напишем на node.JS.

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

Мы воспользуемся библиотекой для реализации web-socket-ов в Node.JS, которую создал Jacek Becela. Её можно скачать по ссылке http://github.com/ncr/node.ws.js . После это её нужно положить в тот же каталог, в котором будет лежать серверная часть нашего чата. Нас интересует именно файл с названием ws.js.

Создадим файл с названием server.js и поместим в него такой код:

var sys = require(«sys»);
// подключаем библиотеку для создания web-socket-сервера
var ws = require(«./ws.js»);
// объявляем массив, в котором будем хранить весь список подключённых пользователей
var clientsArr = [];
// создаем веб-сокет-сервер
var wsServer = ws.createServer(function(websocket) <
// добавляем обработчик события,
// которое сработает при подключении нового пользователя
websocket.addListener(«connect», function() <
// добавляем это соединения в массив пользователей
clientsArr.push(websocket);
sys.debug(«Connection. Clients amount: «+clientsArr.length);
>);
// добавляем обработчик события,
// которое сработает при получении новых данных от пользователя,
// а точнее, когда пользователь отправит сообщение
websocket.addListener(«data», function(data) <
// выведем сообщение в терминал на сервере
sys.debug(data);
// Рассылаем это сообщение всему списку подключенных пользователей
for(var i=0, l=clientsArr.length; i

Сервер на node.JS готов. Запустим его, выполнив команду в консоле:

node server.js

Осталось написать клиентскую часть для нашего чата, приступим.

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

Примечание:
На данный момент веб-сокеты реализованы только в браузерах на основе WebKit, то-есть в Chrome и Safari. Но, можно заставить и другие браузеры работать через веб-сокеты с помощью дополнительных javascript-библиотек, использующих возможности flash-а.
В данной статье это не будет рассматриваться.

Сначала реализуем html-структуру.
Собственно, нам нужно:
— поле для ввода сообщений;
— кнопка, по нажатию которой, сообщение будет отправляться серверу;
— область, в которой будут отображаться все сообщения.

8 Node.js Web Socket Libraries for 2020

Useful libraries for working with web sockets and Node.js

WebSockets make it possible to open an interactive communication session between the user’s browser and a server, to send messages to a server and receive event-driven responses without having to poll the server for a reply.

Although some developers choose to work with the websocket API for asynchronous communication between browsers and servers, issues such as performance, dealing with faulty connections, handling authentication and authorization, or scalability might call for a framework/library.

To help you save time, here is a short list of useful and actively maintained libraries which can come in handy. Feel free to add your own suggestions.

Tip: Use Bit to share and reuse small modules between apps. You can discover and play with components/functions, and install them to build faster. Try it.

1. socket.io

A widely popular and used WebSocket wrapper/API with over 43K stars. Consisting of a Node.js server and a Javascript client library, socket.io provides reliability for handling proxies and load balancers as well as personal firewall and antivirus software and even supports binary streaming. Used by Microsoft, Zendesk and Trello, it even provides real time analytics and can be used for a wide verity of use cases from simple chats to IOT. Here’s a useful tutorial by @davidwalshblog.

With 9k stars WS is a popular WebSocket is a a client/server library for Node.js that helps to manage things under the WebSocket protocol. As the WebSocket protocol is natively supported in most major browsers, some choose to work with WS directly without using socket.io on top. Here’s a quick link to the API docs and here’s a short tutorial with Node.js and express.

3. sockjs

At 6k stars sockjs is a browser JavaScript library that provides a WebSocket-like object with a cross-browser Javascript API which creates a low latency, full duplex, cross-domain communication between the browser and the web server. It follows the HTML5 websocket API and only when it fails it falls back to browser specific protocols. Sockjs-node is the client-library’s counterpart.

4. websocket node

This websocket tool for Node.js has 2k stars and is a mostly pure JavaScript implementation of the WebSocket protocol versions 8 and 13 for Node. WebSocket-Node includes both client and server functionality, available through WebSocketClient and WebSocketServer. Once a connection is established, the API for sending and receiving messages is identical. Here’s a short tutorial for building a simple chat app, and here’s a short presentation.

5. socketcluster

SocketCluster is a scalable HTTP + realtime server engine which lets you build multi-process realtime servers that make use of all CPU cores on a machine/instance. Instead of having to run the Node.js server as a single thread it makes your backend more resilient by automatically recovering from worker crashes and aggregating errors into a central log on each host. At 5k stars, It supports both direct client-server communication and group communication via pub/sub channels.

6. Feathers

At nerly 10k stars Feathers is a real-time, micro-service web framework for NodeJS that gives you control over your data via RESTful resources, sockets (plugin) and flexible plug-ins. The feathersjs/socketio module allows to call service methods and receive real-time eventsvia Socket.io when working with node.js. Here’s a short tutorial for building a simple chat application.

7. faye-websocket-node

A bit old and “only” 500 stars, this project is a standards-compliant WebSocket client and server. It provides classes for building WebSocket servers and clients in Node, but not the server itself or any additional abstraction other than the standard WebSocket API (apart from eventSource connections). There also a Ruby implementation for the concept.

8. websocket as promised

A WebSocket client library providing Promise-based API for connecting, disconnecting and messaging with the server. It’s basically a simple request-response mechanism that returns a promise. To work with Node.js, it should be combined with a third-party node server library like websockets-node. Although only at 200 stars, The project is still under active development.

Honorable mentions

Note that these projects are mostly unmaintained.

Чат в реальном времени в PHP + Redis + Pub/Sub + WebSockets (+ NodeJS)

Я хочу развивать чат реального времени с каналами, и это мои потребности:

  • PHP-сервер для управления сайтом
  • Redis как первичное хранилище данных сеанса и данных
  • Pub/Sub для отправки сообщений только для каналов заинтересованных пользователей.
  • одно соединение WebSocket, с которым будут отправляться и получаться сообщения.
  • (необязательно) NodeJS для использования больших пакетов npm, таких как timesync или socket.io

Я вижу две разные архитектуры:

с Socket.io

с Crossbar.io

Это мои вопросы:

  • Какую архитектуру я должен выбрать и почему?
  • Ключ идентификатор пользователя не может быть получен от клиента, поскольку он может быть искажен. Поэтому в первой архитектуре я думаю, что в каждом сообщении сокета я должен приложить значение PHPSESSID из файла cookie и на стороне сервера получить сеанс PHP из Redis. Я прав, или есть лучший способ получить идентификатор пользователя?
  • Интересно, можно ли получить идентификатор пользователя во второй архитектуре по-другому?

Edit:

Я выбрал Crossbar.io, потому что он очень мощный и позволяет общаться в разных языках в реальном времени. Изучив примеры, я придумал следующее:

В каждом пользователе пользователь создал секретный ключ в базе данных.

Клиент PHP (Thruway) подключается к серверу Crossbar и регистрирует собственный аутентификатор WAMP-CRA

Пользовательский браузер подключается к серверу Crossbar и бросает вызов. Секрет и auth_id (идентификатор пользователя) загружаются из БД с загрузкой страницы, поэтому может выполнить вызов и отправить ответ.

Поиск аутентификации PHP в БД для пользователя с предоставленным секретом и id, равным auth_id. Если есть, то он успешно аутентифицируется сессия. Теперь мы можем верить, что auth_id — это реальный идентификатор пользователя.

Как я могу получить auth_id на подписке?

Я также добавил аутентификацию cookie, и после аутентификации браузер запоминается. Но когда я смотрю в Chrome DevTools, в локальном хранилище есть cookie или значение. Даже после очистки кеша мой браузер по-прежнему помнит Crossbar. Интересно, как это возможно?

Edit2:

Возможно, меня неправильно поняли, но главным вопросом был выбор подходящей архитектуры и получение доверенного идентификатора пользователя. Не было никакого внимания, поэтому я наградил щедростью, и после этого я был ниспослан. Я много читал о приложениях реального времени и, наконец, решил использовать Crossbar.io, поэтому я отредактировал вопрос, связанный с ним. Затем люди начали выживать, предлагая другие архитектуры, но на самом деле не отвечая на мои вопросы. В конце концов, мне удалось сделать это сам и представили свой ответ.

О получении идентификатора пользователя:

Каждый пример чата реального времени, который я видел, получал идентификатор от клиента. Это небезопасно, потому что клиент легко может манипулировать им, поэтому мне нужно было найти другой метод. После прочтения спецификации WAMP Наконец, я выяснил, что мне нужно аутентифицировать пользователя не только в приложении, но и в Crossbar.io. Я выбрал динамический метод WAMP-CRA и реализован следующим образом:

  • Приложение PHP подключается к серверу Crossbar и регистрирует собственный аутентификатор (аналогично example)
  • После входа пользователя в приложение создается секретный ключ для него и сохраняется в базе данных. После выхода из системы ключ уничтожается.

Каждая загруженная страница содержит идентификатор пользователя и секретный ключ, загруженные из db:

  • Пользовательский браузер подключается к серверу Crossbar.io и получает ответ с вызовом пользовательского аутентификатора.
  • Он вычисляет подпись с использованием ключа и отправляет вместе с auth_id на сервер Crossbar.io
  • Аутентификатор получает от секретности БД для предоставленного auth_id и вычисляет подпись. Затем сравниваются сигнатуры, и если они равны, то аутентификация прошла успешно.
  • Теперь auth_id содержит идентификатор пользователя, и мы можем доверять его значению. Теперь вы можете обратиться к разделу «Как я могу получить auth_id для подписки?» .
  • Ответы:

    Как я могу получить auth_id для подписки?


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

    Я также добавил аутентификацию cookie, и после аутентификации браузер запоминается. Но когда я смотрю в Chrome DevTools, в локальном хранилище есть cookie или значение. Даже после очистки кеша мой браузер по-прежнему помнит Crossbar. Интересно, как это возможно?

    Прежде всего, очистка кеша и жесткая перезагрузка не удаляют файлы cookie. Когда я задавал этот вопрос, было представлено какое-либо cookie, но сегодня я вижу cbtid : Обновление было обновлено два дня назад, поэтому, возможно, это было вызвано ошибкой в ​​предыдущей версии.

    Чат на web sockets

    04.02.2013, 08:32

    Чат через модуль Sockets
    Может кто из местных умельцев напишет мне самую простую програму сервер-клиент для отправли и.

    Long polling, web sockets
    Доброго времени суток. Дайте ссылку на какую нить книженцию по лонг пунингу или веб сокетам. В.

    Альтернативы для API web.sockets, Juggernaut не отвечает
    Доброго времени. Внедряюсь в «модные» технологии. Пробовал повторить за скринкастом, по работе с.

    Web чат
    Приветсвую, Понадобилась организовать web-чат между пользователями Домино. Кто нибудь сталкивался.

    Дописать web-чат
    Всем привет, у меня есть задача написать чат, используя исключительно php, js, html, css, я.

    node.js — чат в реальном времени на PHP + Redis + Pub / Sub + WebSockets (+ NodeJS)

    Я хочу разработать чат в реальном времени с каналами, и это мои потребности:

    • PHP-бэкэнд для управления сайтом
    • Redis как сеанс и основное хранилище данных
    • Pub / Sub для отправки сообщений только заинтересованным пользователям канала
    • одно соединение WebSocket, с помощью которого сообщения будут отправляться и приниматься.
    • (необязательно) NodeJS для использования больших пакетов npm, таких как timesync или socket.io

    Я вижу две разные архитектуры для достижения этой цели:

    с Socket.io

    с Crossbar.io

    Это мои вопросы:

    1. Какую архитектуру мне выбрать и почему?
    2. Ключом является то, что идентификатор пользователя не может быть получен от клиента, потому что он может быть искажен. Итак, в первой архитектуре я думаю, что к каждому сообщению сокета я должен прикрепить значение PHPSESSID из cookie, а на стороне сервера — получить сеанс PHP из Redis. Я прав или есть лучший способ получить идентификатор пользователя?
    3. Интересно, можно ли получить идентификатор пользователя во второй архитектуре иначе?

    Редактировать:

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

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

    PHP-клиент (Thruway) подключается к серверу Crossbar и регистрирует собственный аутентификатор WAMP-CRA

    Браузер пользователя подключается к серверу Crossbar и подвергается сомнению. Секрет и auth_id (идентификатор пользователя) загружаются из БД при загрузке страницы, поэтому
    может выполнить вызов и отправить ответ.

    PHP-аутентификатор ищет в БД пользователя с предоставленным секретом и идентификатором, равным auth_id. Если есть, то он успешно аутентифицируется
    сессия. Теперь мы можем верить, что auth_id — это настоящий идентификатор пользователя.

    Как я могу получить auth_id при подписке?

    Я также добавил аутентификацию cookie, и браузер запоминается после аутентификации. Но когда я смотрю в Chrome DevTools в локальном хранилище нет ни cookie, ни значения. Даже после очистки кэша мой браузер все еще запоминается перекладина. Интересно, как это возможно?

    Edit2:

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

    Решение

    Я глубоко осветил Streamer, который используется НАСА для пересылки грузовых данных в секунду. Самый надежный сервер для обмена сообщениями в режиме реального времени.
    Мощные веб-приложения, приложения для мобильных устройств, планшетов, компьютеров и IoT.

    Оптимизированный поток данных для Интернета и мобильных устройств.
    Lightstreamer поддерживает несколько форм обмена сообщениями в реальном времени. Он достаточно гибок, чтобы использоваться в любом сценарии, включая критически важные приложения.
    ► Передача данных в реальном времени и веб-сокеты
    ► Сообщения в приложении и push-уведомления
    ► Паб-саб с разветвленной трансляцией и индивидуальным обменом сообщениями
    ► Брандмауэр и прокси дружественный
    ► Адаптивное регулирование пропускной способности

    Что касается вашего первого вопроса, чтобы получить auth_id для подписки, просто следите за подписками на соединения, а затем сохраняйте уровень при успешном соединении.
    Кроме того, файлы cookie не рекомендуются, используйте jwt.JSON Web Tokens — это открытый, стандартный отраслевой метод RFC 7519 для безопасного представления заявок между двумя сторонами. Аутентификация является одной из основных частей каждого приложения. Безопасность — это то, что постоянно меняется и развивается. JWT помогает вам решить эту проблему. Поскольку она не имеет состояния.

    Другие решения

    PHP Ratchet — одна из лучших реализаций, которую я использовал для связи в реальном времени через WebSockets. Он основан на ZMQ Sockets, который используется в нескольких онлайн-играх и приложениях для чата.

    Следующие примеры помогут вам начать работу довольно быстро и ответят на ваши вопросы о auth_id и подписках:

    Я бы посоветовал создавать отдельные соединения (toppics) для каждого разговора, так как это не влияет на производительность и добавляет дополнительный уровень безопасности для каждого чата.

    Каждый пример чата в реальном времени, который я видел, получал идентификатор от клиента. Это небезопасно, потому что клиент легко может манипулировать им, поэтому мне нужно было найти другой метод. После прочтения Спецификации WAMP Я наконец-то понял, что мне нужно аутентифицировать пользователя не только в приложении, но и в Crossbar.io. Я выбрал динамический метод WAMP-CRA и реализовал его следующим образом:

    • Приложение PHP подключается к серверу Crossbar и регистрирует собственный аутентификатор (аналогично пример )
    • После входа пользователя в приложение генерируется Секретный ключ для него и сохраняется в базе данных. После выхода из системы ключ уничтожается.

    Каждая загруженная страница содержит Идентификатор пользователя а также Секретный ключ загружается из БД:

  • Пользовательский браузер подключается к Crossbar.io сервер и получить ответ с запросом от пользовательского аутентификатора.
  • Это вычислить подпись, используя ключ и отправить вместе с auth_id в Crossbar.io сервер
  • Аутентификатор достает из БД секрет за предоставленный auth_id и рассчитать подпись. Затем сигнатуры сравниваются, и если они равны, аутентификация проходит успешно.
  • Сейчас auth_id содержит идентификатор пользователя, и мы можем доверять его значению. Теперь вы можете ссылаться на раздел ‘Как я могу получить auth_id при подписке?’.
  • Как я могу получить auth_id при подписке?

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

    Я также добавил аутентификацию cookie, и браузер запоминается после аутентификации. Но когда я смотрю в Chrome DevTools, в локальном хранилище нет ни куки, ни значения. Даже после очистки кеша мой браузер до сих пор запоминается по Crossbar. Интересно, как это возможно?

    Прежде всего, очистка кеша и полная перезагрузка не удаляют куки. Когда я задавал этот вопрос, был какой-либо файл cookie, но сегодня я вижу cbtid :

    Два дня назад было обновление Chrome, так что, возможно, это было вызвано ошибкой в ​​предыдущей версии.

    Чат для вашего сайта: NodeJS + WebSockets

    И так как вы могли заметить в Construct 2 есть стандартный плагин с названием «WebSocket». В этом уроке я расскажу для чего он нужен и как с ним работать на примере простого чата а также как запустить сервер на своем ПК. Ниже будут вкладки с описанием каждого этапа а в конце статьи исходник самого чата и соответственно сервер к нему.

    1. Скачиваем с официального сайта последнюю версию Node.js под вашу ОС.
    2. Устанавливаем (все параметры установки оставляем стандартными)
    3. После установки нужно будет проверить node.js. Для этого открываем командную строку и пишем следующее (в конце каждой строки жмем Enter)
    Код: Выделить всё node
    1 + 1

    В ответ вы должны получить число два это значит что node.js работает.
    4. Далее нам нужно будет установить дополнительные пакеты (плагины) на node.js для поддержки websocket’a. Все в той же командной строке нажимаем Ctrl+D и пишем следующее
    Код: Выделить всё npm install node-static

    После того как скачивания и установки пакета, пишем еще одну строку
    Код: Выделить всё npm install ws

    После всех процедур должно получиться как на скриншоте ниже. Если все так то на этом установка и настройка Node.js успешно завершена.

    PS: Если вдруг пакеты не установились стоит попробовать открыть еще раз командную строку от имени администратора и повторить четвертый пункт. Ниже будет видео с установкой Node.js

    Скачиваем ниже исходник чата и открываем его (Нужно установить плагин CSS_Import на Construct 2, выложу его отдельно!) , переходим во вкладку с Events. Прежде всего в самом начале будет глобальная переменная url , в ней нужно будет указать ip адрес и порт машины с сервером, для того чтобы другие устройства смогли подключиться к серверу нужно указать ваш ip внутри локальной вашей сети и не забудьте указать порт сервера к которому мы подключаемся 8081 . Если кто то не знает как его узнать ниже будет один из способов

    В моем случае переменная url будет выглядеть так 192.168.1.86:8081
    Далее о каждом событии используемом в примере:
    Действием «Connect» мы подключаемся к серверу:

    Для отправки любого сообщения используем только одно единственное действие «Send text». Если подключившийся пользователь не имеет ника то мы отправляем серверу его ник.

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

    Когда сервер прислал нам сообщения будь то список пользователей онлайн, или же сообщение от другого пользователя мы используем событие «On message». Далее чтобы понять что именно нам пришло мы при помощи tokenat() сверяем название тега.

    users — все это теги (команды) придуманные для понимания сервером и клиента друг друга. То есть когда мы отправляем сообщение серверу с тегом

    nickname он присваивает пользователю ник.
    По этому исходнику это все.

    1. Скачиваем serverchat.zip распаковываем его в директорию указанную в командной строке (подчеркнут красным)

    2. Пишем следующее и жмем Enter
    Код: Выделить всё node serverchat
    3. Если ответ надпись «Server working» значит сервер успешно запущен на вашем ПК (НЕ закрывайте консоль)
    4. Теперь можно запускать чат (Запустить чат на других устройствах)

    Знакомство с Node.JS: разработка чата

    Итак, немножечко с задержкой, но мы продолжаем писать наше приложение чата на Node.JS. Мы уже вкратце познакомились с этой платформой и запустили свой первый веб-сервер на ней. Пора уже переходить к более серьезным вещам. в целом, если вы хоть немного почитали официальную документацию текущих знаний должно хватить, ну и немного терпения )

    Давайте установим в наш проект еще парочку модулей которые помогут нам разрабатывать фронтенд и делать его красивым: для работы с DOM-элементами мы будем использовать библиотеку jQuery, для верстки — UIKit, а для анимации — Animate.css (можно обойтись и средствами UIKit, но мне их реализация не очень понравилась — многовато специфических багов которые не хочется разбирать). Переходим в консоли в папку с нашим проектом и ставим модули:

    Установили. Теперь подключим эти файлы во фронтенд.

    При написании статьи заметил, что из репозиториев npm пропала версия UIKit 2, и устанавливается 3 с пометкой beta , поэтому в конце статьи приложу архив с нужным модулем, а вы его поместите в папку node_modules в корне вашего проекта, заменив 3ю версию 2й. Ну или если есть желание — можете переписать дальнейшую верстку под 3й — пожалуйста. Я пока жду релиза)

    В папке /public/ открываем наш файл index.html и, удалив все наши «игрульки» из прошлых статей, подключаем все необходимые файлы. Получиться должно примерно так:

    В хедере мы подключаем все необходимые css-стили, в футере, перед закрывающим тегом

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