Перейти до основного вмісту

Створюємо чат

Давайте розберемо створення найпростішого чату за допомогою бібліотеки Socket.io Це наш приклад, який ми будемо розглядати

Реалізація серверної частини досить проста

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);

server.listen(process.env.PORT || 3000, function () {
console.log('Server running in port 3000');
});

app.use(express.static(__dirname + '/public'));

Ми підключаємо всі необхідні нам модулі, запускаємо сервер та вказуємо де будуть лежати статичні ресурси, у нашому випадку клієнтська частина міні-чата

Після цього ми створюємо об'єкт

const users = {};

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

Вся робота чату буде укладена всередині конструкції

io.sockets.on('connection', (client) => {})

Цей код виконається для кожного користувача, що знову підключається за подією connection.

Всередині ми створюємо функцію

const broadcast = (event, data) => {
client.emit(event, data);
client.broadcast.emit(event, data);
};

Ця функція виконує подію event та пересилає дані data конкретно для поточного користувача client.emit(event, data), а потім ініціює подію для всіх інших користувачів, що підключилися client.broadcast.emit(event, data)

При першому підключенні користувача ми виконуємо подію user

broadcast('user', users);

та повідомляємо всім учасникам чату, наш поточний список користувачів

Ще нам знадобляться два обробники для подій message - відправлення повідомлення в чаті та disconnect - Користувач вийшов з чату (закрив вкладку браузера)

Відправка повідомлення

client.on('message', message => {
if (users[client.id] !== message.name) {
users[client.id] = message.name;
broadcast('user', users);
}
broadcast('message', message);
});

Ми перевіряємо є користувач у списку users або можливо змінив ім'я при надсиланні повідомлення та якщо умова виконалася повідомляємо всім користувачам подією user, що це сталося. Після відбувається подія message і ми надсилаємо отримане повідомлення всім користувачам.

Якщо користувач оновив сторінку або закрив вкладку браузера станеться подія disconnect

client.on('disconnect', () => {
delete users[client.id];
client.broadcast.emit('user', users);
});

Ми видаляємо поточного користувача зі списку users і відправляємо всім іншим користувачам через подію user оновлений список. Зверніть увагу, що відправляємо лише решті користувачів. Ось і все, що стосується серверної частини нашої програми.

Клієнтський код не набагато складніший

Ми збираємо в змінні всі необхідні нам DOM елементи

const usersList = document.getElementById('users');
const board = document.getElementById('board');
const userMessage = document.getElementById('msg_txt');
const userName = document.getElementById('msg_name');
const sendButton = document.getElementById('msg_btn');

Підключаємо екземпляр socket.io

const socket = io();

Створюємо масив, де зберігатимемо отримані від сервера повідомлення

const messages = [];

та встановлюємо ліміт на максимальну кількість повідомлень на екрані

const LIMIT_MESSAGES = 10;

Функція renderListOfMessages щоразу при отриманні події message виводить оновлений список повідомлень користувачів на сторінці

Функція renderListOfUsers щоразу при отриманні події user виводить оновлений список користувачів на сторінці

За підключення відповідних обробників відповідає наступний фрагмент коду

socket.on('user', renderListOfUsers);
socket.on('message', renderListOfMessages);

Надсилання повідомлення на сервер виконується функцією sendUserMessage

const sendUserMessage = () => {
let name = userName.value;
const message = userMessage.value;

if (message === '' || name === '') {
return;
}

socket.emit('message', {
message,
name,
});

userMessage.value = '';
userMessage.focus();
};

sendButton.addEventListener('click', sendUserMessage);

Функція

const pressEnterKey = e => {
if (e.keyCode === 13) {
sendUserMessage();
}
};

буде викликати функцію sendUserMessage якщо ми натискаємо клавішу Enter

Як бачимо, вся логіка роботи клієнтського коду побудована на обробці подій user та message, які нам генерує сервер. А також генерування події message для відправки на сервер усередині функції sendUserMessage