Простой чат на node.js
Источники:
https://github.com/bezzad/Simple-broadcast-chat-nodejs-socket.io
http://falbar.ru/article/razrabatyvaem-prostoj-chat-s-pomoshhyu-nodejs-i-socketio
https://medium.com/freecodecamp-russia-русскоязычный/создание-простого-приложения-для-чата-с-помощью-node-js-и-socket-io-eb7498391611
Настройка среды разработки
Создаём папку node-chat
Открываем в vsc, в терминале выполняем команду
npm init -y
Устанавливаем пакеты
- socket.io
npm install socket.io
- express
npm install express
- nodemon
npm install nodemon
- ejs
npm install ejs
В файле package.json пишем код
"scripts": {
"start": "node app",
"dev": "nodemon app"
}
Это позволит запускать приложение командой
npm run dev
Создаём файл app.js - стартовая точка нашего приложения
пишем в app.js тестовый код
const http = require("http");
const server = http.createServer((request, response) => {
response.end("Hello NodeJS!");
});
server.listen(3000, () => {
console.log("Сервер начал прослушивание запросов на порту 3000");
});
По адресу http://localhost:3000/ открываем приложение.
Архитектура приложения
приложение включает в себя две части: клиент и сервер
Серверная часть:
В файле app.js пишем код
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', (req, res) => {
res.send('My first app')
})
const server = app.listen('3000', () => {
console.log('Server is running')
})
Работает
Подключаем socket.io к серверу
const io = require('socket.io')(server);
io.on('connection', (socket) => {
console.log('New user connected')
})
Переходим к клиентской части
Клиентская часть
Заменим в коде
app.get('/', (req, res) => {
res.send('My first app')
})
res.send('My first app') на res.render('index')
Добавляем разметку и стили
Создаём папку views с файлом index.ejs и папку public с файлом style.css
приложение выглядит так (потом улучшим)
Подключаем socket.io к клиенту
В файле index.ejs подключаем скрипты
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="chat.js"></script>
В папке public создаём файл chat.js и пишем код
function startSession() {
const socket = io.connect("http://localhost:3000");
}
startSession()
При перезагрузке страницы приложения в терминале появляется надпись "New user connected"
Отправка и получение данных
Имя пользователя
В файле app.js пишем код:
io.on('connection', (socket) => {
socket.username = 'User';
socket.on('change_username', (data) => {
socket.username = data.username
})
})
Каждый socket это новый пользователь. Мы указали имя пользователя по умолчанию - User, а затем добавили событие с именем 'change_username', и когда это событие произойдёт, имя пользователя изменится на то, которое указано в аргументе
Соответственно, клиент должен это событие сгенерировать
В файле chat.js пишем код
const username = document.querySelector("#username");
const send_username = document.querySelector("#send_username");
send_username.addEventListener('click', () => {
socket.emit("change_username", { username: username.value });
})
Сообщения обрабатываем аналогично
В файле app.js пишем код:
socket.on('new_message', (data) => {
io.sockets.emit('add_message', {
message : data.message,
username : socket.username
});
})
Обращение к io.sockets необходимо для того, чтобы сообщение отправилось всем подключённым пользователям, в том числе и к автору сообщения тоже
В файле chat.js пишем код
send_message.addEventListener('click', () => {
socket.emit('new_message', { message: message.value });
})
socket.on('add_message', (data) => {
const message = document.createElement('div');
message.classList.add('message');
message.innerHTML = `<p><b>${data.username}:</b> ${data.message}</p>`;
chatroom.append(message)
})
При клике по кнопке send_message генерируется событие new_message со значением равным тому тексту, который ввели в поле сообщения
При наступлении события add_message у всех подключенных пользователей в чате отображается отправленное сообщение. Немного стилей помогут раскрасить парные и непарные сообщения в разные цвета
Улучшение чата
Добавим надпись "Пользователь печатает сообщение", когда сообщение набирается
для этого в файле chat.js пишем код
message.addEventListener('keypress', () => {
console.log('typing');
socket.emit('typing');
})
socket.on('typing', (data) => {
feedback.innerHTML = `<p><i>${data.username} is typing a message...</i></p>`;
chatroom.append(message)
})
При нажатии клавиш клавиатуры в окне для ввода сообщения генерируется событие typing.
Код в файле app.js отлавливает это событие, генерирует на его основе новое событие add_typing в котором передаёт имя пользователя
socket.on('typing', (data) => {
io.sockets.emit('add_typing', {
username : socket.username
});
})
При наступлении события add_typing в элементе feedback появляется текст "data.username is typing a message..."
За это отвечает код в файле chat.js
socket.on('add_typing', (data) => {
feedback.innerHTML = `<p><i>${data.username} is typing a message...</i></p>`;
})
При отправке сообщения очищаем элемент feedback
send_message.addEventListener('click', () => {
feedback.innerHTML = '';
})
Собственно, всё. приложение создано и работает используя серверную и клиентскую часть
Код приложения на гитхабе https://github.com/irinainina/node-chat