Node.js 8: WebSocket та Комунікація в реальному часі

pic

Фото Кристофера Робіна Еббінгхауса на Unsplash

Вступ

Реальний час комунікації дозволяє клієнтам і серверам обмінюватися даними без необхідності постійно виконувати запити (polling). За допомогою WebSocket ми можемо створювати з'єднання, яке залишається активним, що дозволяє клієнту та серверу надсилати і отримувати повідомлення у будь-який час.

Приклад застосунків з комунікацією в реальному часі:

  1. Чат додатки: WhatsApp, Telegram або інші месенджери.
  2. Прямі сповіщення: Оновлення статусу замовлення в додатках електронної комерції.
  3. Спільна робота: Додатки, як Google Docs, для спільного редагування документів.

1. Що таке WebSocket?

1.1 Пояснення WebSocket

  • WebSocket — це протокол зв'язку, заснований на TCP, що дозволяє двосторонню комунікацію між клієнтом та сервером.
  • На відміну від HTTP, WebSocket використовує з'єднання, яке завжди активне, що робить його ідеальним для застосунків в реальному часі.

1.2 Різниця між WebSocket та HTTP

pic

2. Початок роботи з WebSocket в Node.js

2.1 Встановлення та налаштування

  1. Встановіть бібліотеку WebSocket: Використовуйте бібліотеку ws для керування з'єднаннями WebSocket:
npm install ws

2. Створіть простий сервер WebSocket: Створіть файл server.js:

const WebSocket = require('ws');  

// Створити сервер WebSocket  
const wss = new WebSocket.Server({ port: 8080 });  

// Подія: коли клієнт підключається  
wss.on('connection', (ws) => {  
 console.log('Клієнт підключений');  

 // Подія: коли сервер отримує повідомлення від клієнта  
 ws.on('message', (message) => {  
 console.log(`Повідомлення отримано: ${message}`);  

 // Відправити відповідь клієнту  
 ws.send(`Повідомлення "${message}" отримано на сервері`);  
 });  

 // Відправити повідомлення клієнту під час підключення  
 ws.send('Ласкаво просимо на сервер WebSocket');  
});  

console.log('Сервер WebSocket працює на ws://localhost:8080');

3. Пояснення:

  • wss.on('connection'): Подія, що спрацьовує, коли клієнт підключається.
  • ws.on('message'): Подія для обробки повідомлень, отриманих від клієнта.
  • ws.send(): Використовується для відправлення повідомлень клієнту.

2.2 Тестування сервера WebSocket

  1. Використовуйте WebSocket клієнт у браузері:
    Відкрийте консоль браузера (Developer Tools) і запустіть наступний код:
const ws = new WebSocket('ws://localhost:8080');  

// Подія: коли з'єднання успішно встановлено  
ws.onopen = () => {  
 console.log('Підключено до сервера WebSocket');  
 ws.send('Привіт від клієнта');  
};  

// Подія: коли повідомлення отримано від сервера  
ws.onmessage = (event) => {  
 console.log('Повідомлення від сервера:', event.data);  
};  

// Подія: коли з'єднання закривається  
ws.onclose = () => {  
 console.log('З'єднання WebSocket закрите');  
};

2. Очікувані результати:

  • Коли клієнт підключається, сервер відправляє повідомлення "Ласкаво просимо на сервер WebSocket".
  • Коли клієнт надсилає повідомлення на сервер, сервер відповідає повідомленням "Повідомлення [вміст повідомлення] отримано на сервері".

3. WebSocket з Express

3.1 Об'єднання WebSocket з Express

1.
Створіть файл app.js:

const express = require('express');  
const http = require('http');  
const WebSocket = require('ws');  

const app = express();  
const server = http.createServer(app); // HTTP сервер  
const wss = new WebSocket.Server({ server }); // Об'єднайте WebSocket з HTTP сервером  

// HTTP Endpoint  
app.get('/', (req, res) => {  
 res.send('Сервер працює з WebSocket');  
});  

// Подія: коли клієнт підключається  
wss.on('connection', (ws) => {  
 console.log('Клієнт підключений');  

 ws.on('message', (message) => {  
 console.log(`Повідомлення від клієнта: ${message}`);  
 ws.send(`Повідомлення "${message}" отримано сервером`);  
 });  
});  

// Запустіть сервер на порту 3000  
server.listen(3000, () => {  
 console.log('Сервер працює на http://localhost:3000');  
 console.log('WebSocket працює на ws://localhost:3000');  
});

4. Приклад використання: Простий чат додаток

4.1 Концепція додатку

Ми створимо простий чат додаток з наступними можливостями:

  1. Клієнт може відправляти повідомлення на сервер.
  2. Сервер поширює це повідомлення серед усіх підключених клієнтів.

4.2 Реалізація сервера чату

  1. Створення серверу чату: Додайте наступний код до server.js:
const clients = new Set(); // Зберігаємо список підключених клієнтів  

wss.on('connection', (ws) => {  
 console.log('Клієнт підключений');  
 clients.add(ws); // Додаємо клієнта до списку  

 ws.on('message', (message) => {  
 console.log(`Повідомлення отримано: ${message}`);  

 // Розсилаємо повідомлення всім клієнтам  
 clients.forEach((client) => {  
 if (client !== ws && client.readyState === WebSocket.OPEN) {  
 client.send(message);  
 }  
 });  
 });  

 ws.on('close', () => {  
 console.log('Клієнт відключився');  
 clients.delete(ws); // Видаляємо клієнта зі списку  
 });  
});

2. Пояснення:

  • Set використовується для зберігання унікальних клієнтів.
  • client.send(message): Відправляє повідомлення всім клієнтам, окрім відправника.

4.3 Тестування чату

  1. Підключення кількох клієнтів:
    Запустіть скрипт клієнта WebSocket в консолі браузера для кількох вкладок.
const ws = new WebSocket('ws://localhost:8080');  

ws.onopen = () => {  
 ws.send('Повідомлення з вкладки 1');  
};  

ws.onmessage = (event) => {  
 console.log('Повідомлення отримано:', event.data);  
};

2. Очікувані результати:

  • Коли один клієнт відправляє повідомлення, всі інші клієнти отримують це повідомлення.

5. Оптимізація та безпека WebSocket

5.1 Аутентифікація у WebSocket

  1. Відправка токену під час підключення: Додайте токен аутентифікації в заголовки при підключенні клієнта:
const ws = new WebSocket('ws://localhost:8080', [], {  
 headers: { Authorization: 'Bearer ' },  
});

2. Перевірка токену на сервері: Перевірте токен, коли клієнт підключається:

wss.on('connection', (ws, req) => {  
 const token = req.headers.authorization?.split(' ')[1];  
 if (!token || token !== 'VALID_TOKEN') {  
 ws.close(1008, 'Токен не дійсний'); // Закрити з'єднання, якщо токен недійсний  
 return;  
 }  
 console.log('Клієнт аутентифікований');  
});

5.2 Лімітування запитів для WebSocket

Використовуйте алгоритм bucket для обмеження кількості повідомлень на клієнта:

const rateLimit = new Map();  

wss.on('connection', (ws) => {  
 rateLimit.set(ws, { count: 0, timer: setInterval(() => rateLimit.get(ws).count = 0, 1000) });  

 ws.on('message', (message) => {  
 const clientRate = rateLimit.get(ws);  
 if (clientRate.count >= 5) {  
 ws.close(1008, 'Занадто багато повідомлень');  
 return;  
 }  
 clientRate.count += 1;  
 console.log('Повідомлення:', message);  
 });  

 ws.on('close', () => clearInterval(rateLimit.get(ws).timer));  
});

6. Завдання та приклади використання

6.1 Завдання

  1. Додайте функцію імені користувача до чату.
  2. Реалізуйте аутентифікацію за допомогою JWT у WebSocket.

6.2 Приклад використання

  • Створіть панель сповіщень в реальному часі, щоб оновлювати дані користувача при зміні з боку сервера.

7. Рефлексія та обговорення

1.
Питання для рефлексії:

  • Які переваги WebSocket порівняно з HTTP для реальних додатків в реальному часі?
  • Як ви забезпечуєте безпеку в додатках WebSocket?

2. Обговорення:

  • Які виклики виникають при обробці великої кількості клієнтів одночасно?
  • Як ви оптимізуєте продуктивність сервера WebSocket для великих масштабів?

Перекладено з: Node.js 8: WebSocket dan Komunikasi Real-Time

Leave a Reply

Your email address will not be published. Required fields are marked *