В этом скрипте вы научитесь создавать динамический чат на NodeJS. Этот чат обновляется на странице автоматически.
Начнем с папки, где будет проект. Создайте папку в удобном месте и создайте в ней файл.
app.js
и файл
messages.json
В файле message.json пропишите это
[]
это будет списком сообщений.
Проверьте установлен ли у вас NodeJS. Если нет - установите.
Зайдите в папку с файлами app.js и messages.json через консоль (в Windows cmd) и введите следующие команды по очереди, чтобы установить нужные модули.
npm install express
npm install socket.io
npm install fs
С установкой модулей закончили, но консоль оставьте открытой для удобства.
Заходим в файл app.js и подключаем наши модули, классы и функции. Пишем:
const express = require("express");
const { createServer } = require("node:http");
const { SocketAddress } = require("node:net");
const { join } = require("node:path");
const { Server } = require("socket.io");
const app = express();
const server = createServer(app);
const io = new Server(server);
const fs = require("fs");
const { stringify } = require("node:querystring");
Теперь пропишем вывод index.html в корне сайта
app.get("/", (req, res) => {
res.sendFile(join(__dirname, "index.html"));
});
Теперь пропишем функционал для подключенного пользователя
io.on("connection", (socket) => {
socket.join("Elite");
data = fs.readFileSync("./messages.json", "utf8");
Messages = JSON.parse(data);
io.to("Elite").emit("msg_taken", Messages);
socket.on("msg", (txt)=>{
data = fs.readFileSync("./messages.json", "utf8");
Messages = JSON.parse(data);
Messages.push(txt);
io.to("Elite").emit("msg_taken", Messages);
dataUpdated = JSON.stringify(Messages, null, 2);
fs.writeFileSync("./messages.json", dataUpdated );
});
});
Здесь все просто, когда человек подключается он попадает в комнату Elite.
socket.join("Elite");
Далее мы считываем синхронно файл messages.json в виде списка и отправляем список сообщений нашему пользователю в комнату Elite.
data = fs.readFileSync("./messages.json", "utf8");
Messages = JSON.parse(data);
io.to("Elite").emit("msg_taken", Messages);
Здесь мы принимаем сообщение txt, считываем файл messages.json как список, пушим наше сообщение в этот список и записываем его в файл messages.json
socket.on("msg", (txt)=>{
data = fs.readFileSync("./messages.json", "utf8");
Messages = JSON.parse(data);
Messages.push(txt);
io.to("Elite").emit("msg_taken", Messages);
dataUpdated = JSON.stringify(Messages, null, 2);
fs.writeFileSync("./messages.json", dataUpdated );
});
Осталось только прописать сервер и порт
server.listen(80, () => {
console.log("server running at http://localhost:80");
});
Мы полностью прописали сервер, переходим к файлу index.html. Для начала создайте его. И откройте текстовым редактором.
Создаём базовую структуру HTML и в head сразу пишем стили
<!DOCTYPE html>
<head>
<style>
#sendForm{
position: fixed;
bottom: 200px;
left: 40%;
text-align: center;
}
#sendForm>p>input, button{
padding: 7px;
margin: 2px;
}
#msg_list{
margin: 160px 0 0 0;
text-align: center;
}
#msg_list>li{
font-size: 16px;
padding: 7px;
list-style:none;
}
#msg_list>li:nth-child(odd) {
background-color: #d6e9ff;
}
#msg_list>li:nth-child(even) {
background-color: #d4ffdf;
}
</style>
</head>
Отлично теперь перейдём к телу, то есть к body
Пишем элементы для отправки и сам список сообщений
<body>
<ul id="msg_list">
</ul>
<div id="sendForm">
<p><input id="msg_line" style="text" placeholder="Сообщение"></p>
<p><button id="msg_btn">Отправить</button></p>
</div>
<script src="/socket.io/socket.io.js"></script>
тег body закроем чуть позже. Нам нужно написать этот скрипт. Сейчас его разберём
<script>
const socket = io();
socket.on("connect", ()=>{
let btn = document.getElementById("msg_btn");
let field = document.getElementById("msg_line");
let msg_list = document.getElementById("msg_list");
btn.addEventListener("click", ()=>{
if(field.value != ""){
socket.emit("msg", field.value);
field.value = "";
field.focus();
}
});
document.body.addEventListener("keypress", function(e){
if (e.key === 'Enter') {
if(field.value != ""){
socket.emit("msg", field.value);
field.value = "";
field.focus();
}
}
});
socket.on("msg_taken", (msgs)=>{
while(msg_list.firstChild) {msg_list.removeChild(msg_list.firstChild)};
for(let i=0; i<msgs.length; i++){
let li = document.createElement("li");
li.appendChild(document.createTextNode(msgs[i]));
msg_list.appendChild(li);
}
});
});
</script>
Закрываем тег body и html
</body>
</html>
Теперь разберем скрипт. В начале - создаём объект socket, в event'e connect
будут происходить все действия со страницей. Это когда пользователь уже подключился.
socket.on("connect", ()=>{
});
Здесь сначала считываем нужные элементы в переменные.
let btn = document.getElementById("msg_btn");
let field = document.getElementById("msg_line");
let msg_list = document.getElementById("msg_list");
Далее при нажатии на кнопку, если поле не пустое, отправляем сообщение и очищаем поле, чтобы не спамить.
btn.addEventListener("click", ()=>{
if(field.value != ""){
socket.emit("msg", field.value);
field.value = "";
field.focus();
}
});
Далее ловим нажатие клавиши Enter, оно делает тоже самое, что и кнопка.
document.body.addEventListener("keypress", function(e){
if (e.key === 'Enter') {
if(field.value != ""){
socket.emit("msg", field.value);
field.value = "";
field.focus();
}
}
});
Ну а в последнем блоке мы ловим сообщения с сервера в виде списка. Сначала очищаем все сообщения на странице первым циклом, далее добавляем по одному элементу из списка в на страницу в наш список с тегом ul
socket.on("msg_taken", (msgs)=>{
while(msg_list.firstChild) {msg_list.removeChild(msg_list.firstChild)};
for(let i=0; i
let li = document.createElement("li");
li.appendChild(document.createTextNode(msgs[i]));
msg_list.appendChild(li);
}
});
Отлично, осталось проверить скрипт, если не закрыли консоль, то пишите в ней. Если закрыли снова зайдите в директорию с вашими файлами. Тут введите команду
node app.js
чтобы запустить скрипт. Зайдите в браузере по адресу
localhost
Так как стоит 80 порт, вводить порт не нужно, но в остальных случаях пишут
localhost:порт
Наш чат готов.