Как сделать сервер WebSocket с помощью JavaScript: мне нравятся мои серверы, как мне нравится мой кофе, мой собственный
10 апреля 2022 г.Большая часть работы, которую мы выполняем с помощью Javascript, связана с отправкой информации с серверов туда и обратно.
Вы, вероятно, знакомы с концепцией API, которые отправляют данные на серверы или веб-сайты в определенном формате, чтобы получить определенный ответ.
Они известны как REST API. Хотя они полезны, они не очень хороши в постоянных потоках данных.
Если вы попытаетесь сделать что-то в реальном времени с помощью REST API, у вас будут плохие времена. К счастью, если нам нужно соединение с пользователем в режиме реального времени, у нас есть альтернатива, известная как WebSockets.
Как работают веб-сокеты
В этом руководстве мы предполагаем, что вы знакомы с Node.JS.
WebSockets — это, по сути, постоянные соединения между сервером и вашим компьютером.
Когда вы заходите на веб-сайт, он может отправить запрос GET на сервер, чтобы инициировать соединение WebSocket между пользователем и сервером.
Веб-сокет против. ОТДЕЛЬНЫЙ API
Если пользователь покидает веб-сайт, соединение прерывается, поэтому пользователь имеет доступ к WebSocket только до тех пор, пока он продолжает использовать веб-сайт.
Как долго WebSocket может оставаться открытым?
После создания WebSocket теоретически он может оставаться открытым вечно. Есть несколько исключений из этого:
- Сервер выходит из строя — это сломает WebSocket, но мы можем попытаться переподключиться к нему.
- Отключение электроэнергии или проблема с интернет-соединением - соединение прервется, если у пользователя прекратится интернет.
- Неактивность — если пользователь не взаимодействует и не отправляет данные через WebSocket, время ожидания соединения неизбежно истекает.
Таким образом, когда мы разрабатываем наш WebSocket, нам нужно подумать, как мы будем повторно подключаться к ним, если соединение пользователя по какой-то причине прерывается, чтобы не прерывать работу пользователя.
Создание WebSocket
Таким образом, WebSocket состоит из двух частей: сервера и локальной машины, которую использует пользователь. Для того, что мы делаем, мы будем использовать Node.JS в качестве нашего сервера, но другие языки также поддерживают WebSockets.
Когда пользователь обращается к нашему веб-сайту, мы загружаем файл с некоторым Javascript, который содержит строку подключения к нашему WebSocket.
Между тем, в нашем бэкэнде у нас будет настроен WebSocket, к которому будет подключаться пользователь. Это показано на диаграмме ниже:
Шаг 1: Создание нашего сервера
Давайте начнем с создания нашего веб-сервера Node.JS для подключения WebSocket. Для этого мы будем использовать экспресс-сервер с дополнительным пакетом под названием express-ws. Этот дополнительный пакет позволит нам использовать ws так же, как мы могли бы использовать get с экспрессом.
Если у вас не установлен Node.JS, вам необходимо сначала сделать это [перейдя по этой ссылке] (https://nodejs.org/en/download/). После установки создайте новую папку с именем server-websocket.
Откройте терминал и используйте cd для перехода в эту папку (если вы не знаете о cd, прочитайте мою статью об этом здесь!).
Создайте папку для вашего WebSocket
Оказавшись в папке, вам необходимо установить пакеты зависимостей. Начните установку своих зависимостей, выполнив каждую из следующих команд:
нпм я выражаю
npm я экспресс-WS
нпм я путь
нпм я URL
После этого создайте файл index.js и вставьте в него следующий код:
```javascript
// Импорт зависимостей пути и URL
импортировать путь из пути
импортировать {fileURLToPath} из 'url'
// Получаем каталог и путь к файлу
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Импорт экспресс, expressWs и http
импортировать экспресс из «экспресс»
импортировать expressWs из 'express-ws'
импортировать http из 'http'
// Наш порт
пусть порт = 3000;
// Приложение и сервер
пусть приложение = экспресс();
пусть сервер = http.createServer(приложение).listen(порт);
// Применение экспресс-запросов
expressWs (приложение, сервер);
app.use(express.static(__dirname + '/views'));
// Получить маршрут /
app.get('/', (требование, разрешение) => {
res.status(200).send("Добро пожаловать в наше приложение");
// Это позволяет серверу выбрать маршрут WebSocket '/ws'
app.ws('/ws', асинхронная функция(ws, req) {
// После чего ждем сообщения и отвечаем на него
ws.on('сообщение', асинхронная функция (msg) {
// Если появится сообщение, мы запишем его в консоль на сервере
console.log(сообщение);
// начинаем слушать сообщения
Последнее предложение, app.ws
, относится к WebSocket, и это то, к чему мы попытаемся подключиться во внешнем интерфейсе.
В настоящее время только консоль WebSocket регистрирует сообщение всякий раз, когда оно получает его от внешнего интерфейса. Давайте изменим это, чтобы оно отправляло что-то обратно:
```javascript
// Получить маршрут веб-сокета /ws
app.ws('/ws', асинхронная функция(ws, req) {
ws.on('сообщение', асинхронная функция (msg) {
// Что было в сообщении?
console.log(сообщение);
// Отправляем обратно некоторые данные
ws.send(JSON.stringify({
"добавить": правда,
"returnText": "Я использую WebSockets!"
Теперь всякий раз, когда это соединение WebSocket получает данные, оно будет отправлять обратно объект, содержащий append и returnText. Мы также запишем в консоль сообщение, полученное сервером.
Затем мы можем манипулировать этим объектом в нашем интерфейсе, чтобы отображать или изменять представления для пользователя.
Сохраните этот файл в папке вашего веб-сервера как index.js. Затем с вашего терминала в папке websocket-server выполните следующую команду:
узел index.js
Шаг 2. Подключение через внешний интерфейс
Теперь у нас есть работающий сервер WebSocket, но нет возможности к нему подключиться. Мы хотим добиться чего-то вроде этого:
- Пользователь посещает наш сайт.
- Мы инициируем соединение WebSocket из нашего файла Javascript.
- Пользователь успешно подключается к WebSocket и отправляет сообщение в WebSocket после подключения.
- Затем мы можем отправить данные обратно пользователю, теперь, когда у него есть живое соединение с нашим сервером WebSocket, создавая обмен данными в реальном времени.
Для нашей демонстрации давайте начнем с создания двух файлов: index.html
и local.js
, оба из которых будут файлами внешнего интерфейса. Далее добавим в наш файл index.html следующее:
```html
<скрипт src="local.js">
Добро пожаловать в WebSockets. Нажмите здесь, чтобы начать получать сообщения.
Далее нам нужно подключить пользователя к нашему WebSocket через файл local.js. Наш файл local.js в конечном итоге будет выглядеть так:
```javascript
// @соединять
// Подключаемся к вебсокету
пусть розетка;
// Это позволит нам создать соединение с веб-сокетом нашего сервера.
// Чтобы это работало, ваш веб-сокет должен работать с узлом index.js
константное соединение = функция () {
// Возвращаем промис, который будет ждать открытия сокета
вернуть новое обещание ((разрешить, отклонить) => {
// Это вычисляет ссылку на веб-сокет.
const socketProtocol = (window.location.protocol === 'https:' ? 'wss:' : 'ws:')
постоянный порт = 3000;
const socketUrl = ${socketProtocol}//${window.location.hostname}:${port}/ws/
// Определяем сокет
// Если вы используете свой веб-сокет на локальном хосте, вы можете изменить
// socketUrl на 'http://localhost:3000', так как мы запускаем наш веб-сокет
// на порту 3000 из предыдущего кода веб-сокета.
сокет = новый WebSocket (socketUrl);
// Это сработает, как только сокет откроется
socket.onopen = (е) => {
// Отправляем немного тестовых данных, которые мы можем использовать на сервере, если захотим
socket.send (JSON.stringify ({ "загружено": правда }));
// Решаем промис - мы подключены
разрешить();
// Это срабатывает, когда сервер отправляет пользователю сообщение
socket.onmessage = (данные) => {
console.log(данные);
// Здесь можно манипулировать любыми данными с сервера.
пусть parsedData = JSON.parse(data.data);
если (parsedData.append === true) {
const newEl = document.createElement('p');
новыйEl.textContent = parsedData.returnText;
document.getElementById('websocket-returns').appendChild(newEl);
// Это сработает при ошибке
socket.onerror = (e) => {
// Возвращаем ошибку, если она возникла
console.log(е);
разрешить();
// Пытаемся снова подключиться
соединять();
// @открыт
// проверяем, открыт ли вебсокет
константа isOpen = функция (ws) {
вернуть ws.readyState === ws.OPEN
// Когда документ загрузился
document.addEventListener('DOMContentLoaded', function() {
// Подключаемся к вебсокету
соединять();
// И добавляем наши прослушиватели событий
document.getElementById('websocket-button').addEventListener('щелчок', function(e) {
если (открыто (гнездо)) {
socket.send(JSON.stringify({
"data": "это наши данные для отправки",
"другое": "это может быть в любом формате"
Может показаться, что это много, но давайте разберемся. В нашей функции подключения мы начинаем с создания нашего URL-адреса WebSocket.
Это можно просто записать как ws://localhost:3000/
, так как наш сервер WebSocket работает на порту 3000
. Выше он настроен на автоматическую настройку, если вы используете HTTP или HTTPS.
Затем мы передаем несколько прослушивателей событий нашему вновь созданному WebSocket. Все наши прослушиватели событий и URL-адрес для подключения к серверу WebSocket находятся в нашей функции connect()
, целью которой является подключение к нашему серверу WebSocket.
Наши прослушиватели событий WebSocket выглядят так:
socket.onopen
- если соединение установлено и открыто, срабатывает.
socket.onmessage
— каждый раз, когда сервер отправляет нам сообщение, это срабатывает. В нашем примере мы добавим новый элемент в HTML-код нашего пользователя, если они получат данные, для которых добавление установлено в true.
socket.onerror
- если соединение не установлено или возникает ошибка, это сработает.
Теперь, когда у нас есть функция connect()
, которая позволяет нам подключаться к нашему серверу WebSocket, мы должны запустить ее. Мы начинаем с ожидания загрузки страницы, используя DOMContentLoaded. Затем мы подключаемся к нашему WebSocket, используя функцию connect()
.
Наконец, мы прикрепляем прослушиватель событий к кнопке на нашей HTML-странице, которая при нажатии теперь будет отправлять некоторые данные в наш WebSocket с помощью функции socket.send()
.
Когда сервер получает эти данные, он затем отправляет обратно свои собственные данные, поскольку срабатывает событие «сообщение» сервера.
```javascript
// Когда документ загрузился
document.addEventListener('DOMContentLoaded', function() {
// Подключаемся к вебсокету
соединять();
// И добавляем наши прослушиватели событий
document.getElementById('websocket-button').addEventListener('щелчок', function(e) {
если (открыто (гнездо)) {
socket.send(JSON.stringify({
"data": "это наши данные для отправки",
"другое": "это может быть в любом формате"
Поскольку наш обработчик событий on message на нашем WebSocket срабатывает всякий раз, когда новые данные поступают с сервера WebSocket, нажатие кнопки заставляет сервер WebSocket отправлять нам сообщение, создавая таким образом новый элемент HTML
.
Вывод
Теперь у нас есть работающий WebSocket, который позволяет отправлять данные на сервер, и обратно пользователю.
Это двустороннее соединение можно использовать, чтобы позволить пользователям взаимодействовать с самим сервером и даже отправлять данные другим пользователям, если вы того пожелаете. Вот несколько полезных ссылок, чтобы узнать больше о WebSockets:
- [Загрузить исходный код через Github.] (https://github.com/smpnjn/express-websocket)
- [Больше руководств по Javascript] (https://fjolt.com/category/javascript)
Ранее опубликовано [здесь] (https://fjolt.com/article/javascript-websockets)
Оригинал