Проблема подключения пользователей к комнате socketio (websocket)
Не так давно я понял, что мне нужно внедрить вебсокет в свой проект, чтобы была синхронизация для всех возможных пользователей. Решил использовать Socket.io для этого.
Конкретную задачу, которую мне нудно решить с помощью вебсокета - это синхронизация таймера у всех пользователей. Меня не устроило изначально, что при каждом новом подключении создается свой socket.id, получается, что каждый в своем мире.
Захотел исправить ситуацию с помощью комнаты, чтобы была единая комната и все к ней подключались, комнату решил сделать просто из url. Все подготовил, но почему-то не работает.
В логах выводится socket.id при подключении, но логи с подключением к комнате не выводятся, ну и соответственно код ниже тоже не отрабатывает логики(таймер).
Перепробовал множество подходов, ничего не помогает. Какая проблема в моем коде?(заранее признаю, что профан в веб-сокетах, только начал изучение)
index.js
const express = require('express');
const PORT = process.env.PORT || 5050;
const userRouter = require('./routes/user.routes');
const gameRouter = require('./routes/game.routes');
const cors = require('cors');
const http = require('http');
const { Server } = require("socket.io");
const { startTimer, getTimerValue, stopTimer } = require('./socket');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
}
});
// const joinRoom = (socket, room) => {
// socket.join(room);
// socket.emit('message', `welcome to ${room}!`);
// }
const joinRoom = (socket, room) => {
socket.join(room);
io.to(room).emit('message', `Добро пожаловать в комнату ${room}!`);
}
io.on('connection', (socket) => {
console.log('Новое подключение', socket.id);
socket.on('join', (room) => {
joinRoom(socket, room);
})
socket.on('startTimer', (timerValue) => {
startTimer(socket, timerValue);
});
socket.on('timer:update', (timerValue)=>{
socket.broadcast.emit('timer:update', timerValue);
})
socket.on('disconnect', () => {
console.log('Сокет отключен', socket.id);
});
});
const corsOptions = {
origin: '*',
methods: "*",
allowedHeaders: "*"
};
app.use(cors(corsOptions));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/api', userRouter);
app.use('/game', gameRouter);
server.listen(PORT, () => console.log(`Cтарутем на порту ${PORT}`));
socket.js(timer)
let timerValue = 0;
let timerInterval;
const startTimer = (socket, initialTimerValue) => {
timerValue = initialTimerValue;
timerInterval = setInterval(() => {
timerValue--;
socket.emit('timer:update', timerValue);
if (timerValue === 0) {
clearInterval(timerInterval);
}
}, 1000);
};
const getTimerValue = () => {
return timerValue;
};
const stopTimer = () => {
clearInterval(timerInterval);
};
module.exports = { startTimer, getTimerValue, stopTimer };
часть кода react.jsx
import React, { useState, useEffect, useRef } from "react";
import './FirstGame.css'
import Timer from '../components/Timer.jsx'
import io from 'socket.io-client';
import {useLocation} from 'react-router-dom'
const FirstGame = () => {
const [value, setValue] = React.useState(361);
const [resultNumber, setResultNumber] = React.useState(null);
const [countdown, setCountdown] = React.useState(11);
const itemsPerPage = 10;
const indexOfLastItem = currentPage * itemsPerPage;
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
const currentItems = lastResult.slice().reverse().slice(indexOfFirstItem, indexOfLastItem);
const latestNumber = gameHistory.length > 0 ? gameHistory[gameHistory.length - 1].number : null;
const color = gameHistory.length > 0 ? gameHistory[gameHistory.length - 1].color : null;
const startCountdown = () => {
let timer = 11;
const timerInterval = setInterval(() => {
timer--;
setCountdown(timer);
if (timer === 0) {
clearInterval(timerInterval);
}
}, 1000);
return () => {
clearInterval(timerInterval);
};
};
const { pathname } = useLocation();
let room = localStorage.getItem('room');
if (!room) {
room = pathname.slice(1);
localStorage.setItem('room', room);
}
useEffect(() => {
const socket = io('http://localhost:5050');
socket.on("connect", () => {
console.log("Соединение установлено", socket.id);
});
socket.emit('join', room);
socket.on('message', () => {
console.log('Подключение к комнате:', room);
})
socket.on("disconnect", () => {
console.log("Соединение разорвано с сокетом", socket.id);
});
socket.on("timer:update", (timerValue) => {
setCountdown(timerValue);
})
return () => {
socket.disconnect();
};
}, [room]);