Подготовка проекта
Разработка велась в Visual Studio Code в Windows 10 PRO. Для меня было важно, чтобы VSCode был с Github Copilot.
node -v
v22.14.0
npm -v
10.9.2
Создаём директорию для проекта, я назвал его espia, шпион по испански (мне нравится испанский). Заходим в неё и инициализируем проект.
cd espia
npm init
в package.json добавляем
"type": "module",
в текущей директории проекта создаем директорию data, и в ней два файла: images.json и phrases.json. Это будет наша "База данных" со списком случайных картинок и фраз. Под списком будем понимать массив объектов. В интернете я нашел ресурс, который их бесплатно раздаёт, оттуда и позаимствовал.
Пример json для картинок:
[{
"image_url": "https://images.freeimages.com/images/large-previews/07f/settlers-of-catan-2-1192459.jpg",
"description": "Catan"
},
{
"image_url": "https://images.freeimages.com/images/large-previews/544/sorry-game-pieces-1424181.jpg",
"description": "Green pieces"
}]
Пример json для фраз:
[{
"phrase": "A Busy Body",
"meaning": "Someone who gets into other people's business."
},
{
"phrase": "A Cat Nap",
"meaning": "A short slumber taken during the day."
}]
Хочется отметить, что перед тем как прийти к этому решению было опробовано несколько бесплатных сервисов, которые по какому-то урл-у возвращают случайную картинку (в некоторых, даже можно было задавать в урл-е тематику и размеры), однако ни один из них так и не подошел. То он просто не работал, то работал не стабильно, через раз, то каждый раз возвращал одну и ту же картинку. Были даже идеи парсить страницу имейдж стоков (где каждый раз загружается много случайных фоток, картинок, также там можно задавать различные фильтры, ту же тематику например) и выбирать какую-то одну. Но такое решение добавило бы еще одно звено ненужной зависимости.
BACK END: НАЧАЛО
Возвращаемся в корневую директорию проекта и создаём там файл server.js с таким содержимым (проверяем выбор случайной фразы из файла json):
import { readFileSync } from 'node:fs';
try {
//get random phrase
const data = JSON.parse(readFileSync('data/phrases.json', 'utf8'));
const phraseIndex = Math.floor(Math.random() * data.length);
console.log(phraseIndex, data[phraseIndex]);
}
catch (err) {
console.error(`Error reading JSON file: ${err}`);
}
Проверяем:
node server.js
61 {
phrase: 'Fish Out Of Water',
meaning: 'Someone being in a situation that they are unfamiliar or unsuited for.'
}
Установим библиотеки для express сервера, вебсокетов и работы с переменными окружения:
npm install express socket.io dotenv
Подключаем их и создаём сервер
import dotenv from 'dotenv';
import express from 'express';
import { Server } from 'socket.io';
const app = express();
const port = process.env.PORT || 3000;
var server = app.listen(port, function(){
console.log("Listening to port ", port);
});
const io = new Server(server, {
cors: {
origin: "*",
methods: ["GET", "POST"]
}
});
io.on('connection', (socket) => {
console.log('New client connected:', socket.id);
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
});
});
Вынесем номер порта в переменную окружения. Для этого создаём в корне проекта файл .env с содержимым:
PORT=3000
Проверим если всё работает
npm start
> espia@1.0.0 start
> node server.js
Listening to port 3000
FRONT END: НАЧАЛО
Для проверки вебсокетов клиентских соединений будем использовать только что созданный сервер. Клиентскую часть будем хостить из директории public, поэтому создадим её в корне проекта. Так как фронт и бэк на одном сервере, cors нам пока не нужны, закомментируем их.
io.on('connection', (socket) => {
console.log('New client connected:', socket.id);
socket.on('disconnect', () => {
console.log('Client disconnected:', socket.id);
});
});
Перейдём в директорию public и создадим там файл index.html и подключим вебсокеты:
<!DOCTYPE html>
<html>
<head>
<title>Socket Client Test</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js" integrity="sha384-mkQ3/7FUtcGyoppY6bz/PORYoGqOl7/aSUMn2ymDOJcapfS6PHqxhRTMh1RR0Q6+" crossorigin="anonymous"></script>
</head>
<body>
</body>
<script type="text/javascript" src="client.js"></script>
</html>
И client.js откуда будем устанавливать соединение
//var socket = io.connect("http://localhost:3000");
var socket = io();
Запустим сервер npm start и перейдём в браузере http://localhost:3000/
В консоли браузера должно появиться что-то типа
New client connected: FgeGE4u9TZW_VCPAAAAB
Продолжение следует ...
