Timer ignoring checks and immediately starting in socket.io

The chat application is built on Node.js utilizing Socket.io and express for real-time client-server communication. The software is designed to handle up to 3 users and the chat doesn’t start unless there’s a minimum of 3 users connected.The issue lies in the timer logic in the chat application. The timer is supposed to start only when the minimum number of users (3 users) is connected. However, the timer appears to start even with fewer users when a user disconnevts.We have revised the code to ensure checks for minimum users before starting the timer, specifically within the ‘disconnect’, ‘set-username’, and ‘Input Submit’ events. But it seems the timer is still activating with fewer users starting immediatly after the third user leaves the room but freezing  when it reaches 1 second , important to note that we didn’t test by sending messages we tested by the timer display each user is given 20 seconds  to write a message if the timer displayes this means its the user turn There might possibly be an issue with the scope of the variable that is controlling the timer activation (‘TimerActive’) or the way the timer is initialized and cleared.The goal is to ensure that the timer function (startTurnTimer) only activates when the minimum number of users is connected, and when user disconnects, timer should restart if remaining connected users equal or exceed the minimum, or halt otherwise

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
app.use(express.static('public'));
let connectedUsers = [];
let maxUsers = 3; // max users allowed
let minUsers =3; //minimum users for the game to start
let turnIndex = 0;
let turnTimer = null;
let TimerActive=false;
const turnTimeout = 20; // 20 seconds
function startTurnTimer() {
let remainingTime = turnTimeout;
TimerActive = true; // Set timer activity to true, as it started
turnTimer = setInterval(() => {
remainingTime--;
if (remainingTime <= 0) {
io.to(connectedUsers[turnIndex].id).emit('turn-timeout');
NextTurn();
} else {
io.to(connectedUsers[turnIndex].id).emit('timer', remainingTime);
}
}, 1000); // Update timer every second
}
function IsMinimum () {
if (connectedUsers.length >= minUsers) {
return true;
} else {
return false;
}
}
function IsTurn (SocketID){
if (connectedUsers[turnIndex] && SocketID === connectedUsers[turnIndex].id){
return true;
} else{
return false;
}
}
function NextTurn (){
if (connectedUsers.length === 0) {
return;
}
turnIndex = (turnIndex + 1) % connectedUsers.length;
}
io.on('connection', (socket) => {
if (connectedUsers.length >= maxUsers) {
console.log('Chat is full, rejecting connection.');
// Immediately emit a "chat full" event to the new user
socket.emit('full');
socket.disconnect(true); // Disconnect the user
return;
}else{
socket.emit('joined'); /* verify that a user joined */
//let CurrentUser="";
socket.on('set-username', (username) => {
//CurrentUser=username;
const user = { id: socket.id, username: username };
connectedUsers.push(user);
console.log('A user connected!', connectedUsers);
socket.emit('user-count', connectedUsers.length);
socket.broadcast.emit('user-count', connectedUsers.length);
//if the game has the minimum no. of users and a timer has not previously started
if (IsMinimum() && !TimerActive) { //when no timer is already active to avoid multiple timers
startTurnTimer();
}
});
// Listen for chat messages from clients
socket.on('Input Submit', (msg) => {
let UsersCheck=IsMinimum(); //check if the minimum no. of users are connected already
let TurnCheck = IsTurn(socket.id); //check if it is the user's turn to send a message
//first we will check that the minimum no. of users is at least the max no. specified above
if (UsersCheck === true) {
io.emit('all_users_connected');
if (TurnCheck === true) {
io.emit('Input Submit', {
msg
});
NextTurn(); //go to the next turn
startTurnTimer();
} else {
console.log('It is not your turn to send a message.');
socket.emit('no_turn');
}
} else {
socket.emit('no_users');
}
/* io.emit('Input Submit', { msg }); */
}
);
socket.on('disconnect', () => {
//if it is his turn move to the next turn before deleting him
if (IsTurn(socket.id)) {
NextTurn();
}
// Reset the timer
clearInterval(turnTimer);
turnTimer = null;
TimerActive = false;
if (IsMinimum()) {
startTurnTimer();
}
// Remove the disconnected user from the array
connectedUsers = connectedUsers.filter(user => user.id !== socket.id);
// Emit updated user count to all clients
io.emit('user-count', connectedUsers.length);
socket.broadcast.emit('user-count', connectedUsers.length);
console.log('A user disconnected!');
});
}
});
server.listen(5000, () => {
console.log(' Server listening on port 3000');
});
</code>
<code>const express = require('express'); const app = express(); const http = require('http'); const server = http.createServer(app); const { Server } = require("socket.io"); const io = new Server(server); app.use(express.static('public')); let connectedUsers = []; let maxUsers = 3; // max users allowed let minUsers =3; //minimum users for the game to start let turnIndex = 0; let turnTimer = null; let TimerActive=false; const turnTimeout = 20; // 20 seconds function startTurnTimer() { let remainingTime = turnTimeout; TimerActive = true; // Set timer activity to true, as it started turnTimer = setInterval(() => { remainingTime--; if (remainingTime <= 0) { io.to(connectedUsers[turnIndex].id).emit('turn-timeout'); NextTurn(); } else { io.to(connectedUsers[turnIndex].id).emit('timer', remainingTime); } }, 1000); // Update timer every second } function IsMinimum () { if (connectedUsers.length >= minUsers) { return true; } else { return false; } } function IsTurn (SocketID){ if (connectedUsers[turnIndex] && SocketID === connectedUsers[turnIndex].id){ return true; } else{ return false; } } function NextTurn (){ if (connectedUsers.length === 0) { return; } turnIndex = (turnIndex + 1) % connectedUsers.length; } io.on('connection', (socket) => { if (connectedUsers.length >= maxUsers) { console.log('Chat is full, rejecting connection.'); // Immediately emit a "chat full" event to the new user socket.emit('full'); socket.disconnect(true); // Disconnect the user return; }else{ socket.emit('joined'); /* verify that a user joined */ //let CurrentUser=""; socket.on('set-username', (username) => { //CurrentUser=username; const user = { id: socket.id, username: username }; connectedUsers.push(user); console.log('A user connected!', connectedUsers); socket.emit('user-count', connectedUsers.length); socket.broadcast.emit('user-count', connectedUsers.length); //if the game has the minimum no. of users and a timer has not previously started if (IsMinimum() && !TimerActive) { //when no timer is already active to avoid multiple timers startTurnTimer(); } }); // Listen for chat messages from clients socket.on('Input Submit', (msg) => { let UsersCheck=IsMinimum(); //check if the minimum no. of users are connected already let TurnCheck = IsTurn(socket.id); //check if it is the user's turn to send a message //first we will check that the minimum no. of users is at least the max no. specified above if (UsersCheck === true) { io.emit('all_users_connected'); if (TurnCheck === true) { io.emit('Input Submit', { msg }); NextTurn(); //go to the next turn startTurnTimer(); } else { console.log('It is not your turn to send a message.'); socket.emit('no_turn'); } } else { socket.emit('no_users'); } /* io.emit('Input Submit', { msg }); */ } ); socket.on('disconnect', () => { //if it is his turn move to the next turn before deleting him if (IsTurn(socket.id)) { NextTurn(); } // Reset the timer clearInterval(turnTimer); turnTimer = null; TimerActive = false; if (IsMinimum()) { startTurnTimer(); } // Remove the disconnected user from the array connectedUsers = connectedUsers.filter(user => user.id !== socket.id); // Emit updated user count to all clients io.emit('user-count', connectedUsers.length); socket.broadcast.emit('user-count', connectedUsers.length); console.log('A user disconnected!'); }); } }); server.listen(5000, () => { console.log(' Server listening on port 3000'); }); </code>
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);

app.use(express.static('public'));

let connectedUsers = [];
let maxUsers = 3; // max users allowed
let minUsers =3; //minimum users for the game to start
let turnIndex = 0;
let turnTimer = null;
let TimerActive=false;



const turnTimeout = 20; // 20 seconds

function startTurnTimer() {
  let remainingTime = turnTimeout;
  TimerActive = true; // Set timer activity to true, as it started


  turnTimer = setInterval(() => {
    remainingTime--;
    if (remainingTime <= 0) {
      io.to(connectedUsers[turnIndex].id).emit('turn-timeout');
      NextTurn();
    } else {
      io.to(connectedUsers[turnIndex].id).emit('timer', remainingTime);
    }
  }, 1000); // Update timer every second
}


function IsMinimum () {
  if (connectedUsers.length >= minUsers) {
    return true;
  } else {
    return false;

  }

}
function IsTurn (SocketID){
  
  if (connectedUsers[turnIndex] && SocketID === connectedUsers[turnIndex].id){
    return true;
  } else{
    return false;
  }
}

function NextTurn (){
  if (connectedUsers.length === 0) {
    return;
  }

  turnIndex = (turnIndex + 1) % connectedUsers.length;

}








io.on('connection', (socket) => {
  if (connectedUsers.length >= maxUsers) {
    console.log('Chat is full, rejecting connection.');
    // Immediately emit a "chat full" event to the new user
    socket.emit('full');
    socket.disconnect(true); // Disconnect the user
    return;
  }else{
    socket.emit('joined'); /* verify that a user joined */

    //let CurrentUser="";

    socket.on('set-username', (username) => {
      //CurrentUser=username;
      
      const user = { id: socket.id, username: username };
      connectedUsers.push(user);
      console.log('A user connected!', connectedUsers);
      socket.emit('user-count', connectedUsers.length);
      socket.broadcast.emit('user-count', connectedUsers.length); 

      //if the game has the minimum no. of users and a timer has not previously started
      if (IsMinimum() && !TimerActive) {   //when no timer is already active to avoid multiple timers
        startTurnTimer();
      }

  
    });






  // Listen for chat messages from clients
  socket.on('Input Submit', (msg) => {
      let UsersCheck=IsMinimum(); //check if the minimum no. of users are connected already
      let TurnCheck = IsTurn(socket.id); //check if it is the user's turn to send a message

      //first we will check that the minimum no. of users is at least the max no. specified above
      if (UsersCheck === true) {
        io.emit('all_users_connected');
        if (TurnCheck === true) {
          io.emit('Input Submit', {
            msg
          });


          NextTurn(); //go to the next turn
          startTurnTimer();

        } else {
          console.log('It is not your turn to send a message.');
          socket.emit('no_turn');
        }

      } else {
        socket.emit('no_users');
      }

      /*    io.emit('Input Submit', {  msg }); */
    }

  );

  socket.on('disconnect', () => {
    //if it is his turn move to the next turn before deleting him
    if (IsTurn(socket.id)) {

      NextTurn();

    }
    
    // Reset the timer
    clearInterval(turnTimer);
    turnTimer = null;
    TimerActive = false;

    if (IsMinimum()) {
      
        startTurnTimer();   
   
    }
    

    // Remove the disconnected user from the array
    connectedUsers = connectedUsers.filter(user => user.id !== socket.id);
  
    // Emit updated user count to all clients
    io.emit('user-count', connectedUsers.length);
    socket.broadcast.emit('user-count', connectedUsers.length); 

  

  
    console.log('A user disconnected!');

  });
  }
});

server.listen(5000, () => {
  console.log('  Server listening on port 3000');
});

I tried refining the logic when a user disconnect multiple times adding more flags and checks but something else is triggering the timer

New contributor

Amir Amgad is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật