Hi,
I’m currently working on creating a simple chat app, but have run into a problem after trying to display usernames. Everything works great up until the disconnect, where Socket.IO seems to forget the socket’s username and displays “transport close has disconnected” in the Terminal and “undefined has disconnected.” on the app itself.
Does anyone have an idea of how I can fix this, and I’m open to other code improvements as well, I just learned the basics of Socket.IO and designed the username system entirely myself, so I’m not sure if I’m doing it the best way.
(Also, another issue if someone wants to go above and beyond. My code that prevents users from accessing certain usernames (such as Server) doesn’t seem to be working. I’ve already thought of a better way to implement it, but I’m still wondering why it seems to be failing.)
server.js
const path = require("path");
const ejs = require("ejs");
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);
const PORT = process.env.PORT;
app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.get("/", (req, res) => {
res.render("index");
});
io.on("connection", (socket) => {
socket.on("username", (username) => {
socket.broadcast.emit("connected", username);
console.log(`${username} has connected`);
socket.on("message", (message) => {
socket.broadcast.emit("message", message, username);
console.log(`${username}: ${message}`);
});
socket.on("disconnect", (username) => {
socket.broadcast.emit("disconnected");
console.log(`${username} has disconnected`);
});
});
});
server.listen(PORT, () => {
console.log(`Listening on *:${PORT}`);
});
client.js
const socket = io();
const form = document.getElementById("form");
const message = document.getElementById("input");
const messages = document.getElementById("messages");
const allowedChars = "abcdefghijklmnopqrstuvwxyz1234567890_";
const invalidUsers = ["Server"];
function getUsername(allowedChars, invalidUsers) {
let username = null;
let promptWith = "Enter Username: ";
function checkChars() {
for (let i = 0; i <= username.length; i++) {
if (allowedChars.indexOf(username[i].toLowerCase()) === -1) {
promptWith =
"Username includes invalid characters\nEnter Username: ";
return false;
}
return true;
}
}
function checkUsers() {
let lowercaseInvalidUsers = [];
for (i of invalidUsers) {
lowercaseInvalidUsers.push(i.toLowerCase());
}
if (username in lowercaseInvalidUsers) {
promptWith =
"Chosen username is reserved or disallowed\nEnter Username: ";
return false;
}
return true;
}
while (true) {
do {
username = prompt(promptWith);
} while (username === null || username === "");
if (!checkChars()) {
continue;
} else if (!checkUsers()) {
continue;
}
break;
}
return username;
}
const username = getUsername(allowedChars, invalidUsers);
socket.emit("username", username);
function displayMessage(message, username) {
const msgli = document.createElement("li");
msgli.innerHTML = `<strong>${username}</strong> <p>${message}</p>`;
messages.appendChild(msgli);
window.scrollTo(0, document.body.scrollHeight);
}
form.addEventListener("submit", function (e) {
e.preventDefault();
if (message.value) {
displayMessage(message.value, username);
socket.emit("message", message.value);
message.value = "";
}
});
socket.on("connected", function (username) {
displayMessage(`${username} has connected.`, "Server");
});
socket.on("disconnected", function (username) {
displayMessage(`${username} has disconnected.`, "Server");
});
socket.on("message", function (message, username) {
displayMessage(message, username);
});
If anyone needs my entire project, the GitHub repo can be found below. Thank you!