Socket.io — показывает аргумент как «неопределенный» и случайным образом останавливает приложение

#javascript #node.js #server #socket.io

Вопрос:

Я работаю над простым приложением для чата, которое изначально было разветвлено из репозитория GitHub. Это работает, но есть ошибка, которая возникает случайным образом и останавливает запуск приложения.

Код на стороне сервера

 const path = require('path');
const http = require('http');
const express = require('express');
const socketio = require('socket.io');
const formatMessage = require('./utils/messages');
const {
  userJoin,
  getCurrentUser,
  userLeave,
  getRoomUsers
} = require('./utils/users');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

// Set static folder
app.use(express.static(path.join(__dirname, 'public')));

const botName = 'CCBot';
v = process.env;
// Run when client connects
io.on('connection', socket => {
  socket.on('joinRoom', ({ token, username, room }) => {
    console.log(token, username, room)
    if (token == v.TOKEN_1){username = v.N_1}
    else if (token == v.TOKEN_2){username = v.N_2}
    else if (token == v.TOKEN_3){username = v.N_3}
    else{
      socket.emit("redirect"); return
    } 

        
      const user = userJoin(socket.id, username, room, token, false);
      
      socket.join(user.room);

      // Welcome current user
      socket.emit('message', formatMessage(botName, 'Welcome!'));

      // Broadcast when a user connects
      socket.broadcast
        .to(user.room)
        .emit(
          'message',
          formatMessage(botName, `${user.username} has joined the chat!`, 'green')
        );

      // Send users and room info
      io.to(user.room).emit('roomUsers', {
        room: user.room,
        users: getRoomUsers(user.room)
      });


    });

    // Listen for chatMessage
    socket.on('chatMessage', (msg) => {
      const user = getCurrentUser(socket.id)
      console.log(user)
      //The error originates on the below line
      io.to(user.room).emit('message', formatMessage(user.username, msg, )); //The error occurs here
    });

    socket.on('userLeave', (id) => {
      const user = getCurrentUser(id)
      console.log(user)
      socket.emit("sendMessages", user)
    })

    // Runs when client disconnects
    socket.on('disconnect', () => {
      const user = userLeave(socket.id);

      if (user) {
        io.to(user.room).emit(
          'message',
          formatMessage(botName, `${user.username} has left the chat.`, "red")
        );

        // Send users and room info
        io.to(user.room).emit('roomUsers', {
          room: user.room,
          users: getRoomUsers(user.room)
        });
      }
  });
});

const PORT = process.env.PORT || 3000;

server.listen(300, () => console.log(`Server running on port 3000`));
 

Функции Util

 const users = [];
// Join user to chat
function userJoin(id, username, room, auth, admin ) {  

  const user = { id, username, room, admin };

  users.push(user);

  return user;
}

// Get current user
function getCurrentUser(id) {
  return users.find(user => user.id === id);
}

// User leaves chat
function userLeave(id) {
  const index = users.findIndex(user => user.id === id)
  if (index !== -1) {
    return users.splice(index, 1)[0];
  }
}

// Get room users
function getRoomUsers(room) {
  return users.filter(user => user.room === room);
}

module.exports = {
  userJoin,
  getCurrentUser,
  userLeave,
  getRoomUsers
};
 
 function formatMessage(username, text, color) {
  return {
    username,
    text,
    time: moment().tz("My Timezone here.").format('h:mm a'),
    color
  };
}

module.exports = formatMessage;
 

Client Side

 let notif = undefined;
// Get username and room from URL
const { username, room, token, t2 } = Qs.parse(location.search, {
  ignoreQueryPrefix: true,
});
listUsers = [];

const socket = io();

// Join chatroom
socket.emit('joinRoom', { username, room, token });

// Get room and users
socket.on('roomUsers', ({ room, users }) => {
  outputRoomName(room);
  outputUsers(users);
});

socket.on("redirect", () => {
  try { window.location = "wrongpassword.html" }
  catch (e) {
    window.location = "about:blank"
  }
})

// Message from server
socket.on('message', (message) => {
  console.log(message);
  outputMessage(message);

  // Scroll down
  chatMessages.scrollTop = chatMessages.scrollHeight;
});

socket.on("sendMessages", user => {
  banned.push(user.username)
  socket.emit("BAN_ALERT")
})

// Message submit
chatForm.addEventListener('submit', (e) => {
  e.preventDefault();

  // Get message text
  let msg = e.target.elements.msg.value;

  msg = msg.trim();

  if (!msg) {
    return false;
  }

  // Emit message to server
  socket.emit('chatMessage', msg);

  // Clear input
  e.target.elements.msg.value = '';
  e.target.elements.msg.focus();
});

function enableNotif(){
  notif = true;
}

function disableNotif(){
  notif = false;
}
// Output message to DOM

function outputMessage(message) {
  if (message.text == ".clear" || message.text == 
  ".c") {
    try {
      document.querySelector(".chat-messages").innerHTML = ""
      return
    }
    catch (e) {
      window.location.reload(true)
      return
    }
    }

  else if (message.text == ".exit" || message.text == ".e"){
    location = "about:blank"
  }

  else if (message.text == ".users"){
    console.log(userList)
    div = document.createElement('div');
    div.classList.add('message');
    const p = document.createElement('p');
    p.classList.add('meta');
    p.innerText = "CCBot";
    p.innerHTML  = ` <span>${message.time}</span>`;
    
    div.appendChild(p);
    const para = document.createElement('p');
    para.classList.add('text');
    para.innerText = listUsers;
    color = "black";
    if(color){para.style.color = color}
    else{para.style.color = "black"}
    div.appendChild(para);
    document.querySelector('.chat-messages').appendChild(div);
  }

  else {
    const div = document.createElement('div');
    div.classList.add('message');
    const p = document.createElement('p');
    p.classList.add('meta');
    p.innerText = message.username;
    p.innerHTML  = ` <span>${message.time}</span>`;
    
    div.appendChild(p);
    const para = document.createElement('p');
    para.classList.add('text');
    para.innerText = message.text;
    color = message.color;
    if(color){para.style.color = color}
    else{para.style.color = "black"}
    div.appendChild(para);
    document.querySelector('.chat-messages').appendChild(div);
    if (notif) {
      var audio = new Audio('./media/notif.mp3');
      console.log(audio)
      audio.play();
    }
    
  }
}

// Add room name to DOM
function outputRoomName(room) {
  roomName.innerText = room;
}



// Add users to DOM
function outputUsers(users) {
  userList.innerHTML = '';
  users.forEach((user) => {
    const li = document.createElement('li');
    li.innerHTML = `${user.username} <br><hr>`;
    li.style = "cursor:pointer;"
    userList.appendChild(li);
    listUsers.push(li.innerText)
  });
}



//Prompt the user before leave chat room
document.getElementById('leave-btn').addEventListener('click', () => {
  const leaveRoom = confirm('Are you sure you want to leave the chatroom?');
  if (leaveRoom) {
    window.location = '../index.html';
  } else {
  }
});
 

Ошибка

 TypeError: Cannot read property 'room' of undefined
at Socket.socket.on.msg (/home/duck/server.js:51:16)
at Socket.emit (events.js:198:13)
at /home/duck/node_modules/socket.io/lib/socket.js:528:12
at process._tickCallback (internal/process/next_tick.js:61:11)
/home/duck/server.js:51
io.to(user.room).emit('message', formatMessage(user.username, msg));
^
 

В репо уже открыта эта проблема, но ответа на нее нет.
Я не уверен, почему возникает ошибка.
Заранее спасибо.
P. S, Пожалуйста, игнорируйте все, что связано с запретом/удалением пользователей.

Комментарии:

1. Если пользователь, который не прошел надлежащую проверку подлинности (= вы не можете найти текущий объект пользователя), отправляет сообщение, вам следует просто не обрабатывать его, вместо того, чтобы аварийно завершать работу…

2. @CherryDT if (!(user)){return} Это то, что ты предлагаешь?