When a user leaves the chat page, related socket client could inform socket server for it to broadcast this information to all connected socket clients. In this case, socket server could delete the user who left the chat page from the users collection object and broadcast this new users object to socket clients.
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Khmer Web Chat</title>
<link rel="stylesheet" href="/base.css" />
<link rel="stylesheet" href="/chat.css" />
<link href="/fonts/setup.css" rel="stylesheet" />
<link href="/logo.png" rel="icon" />
</head>
<body>
<section class="Chat region">
<div class="main">
<div class="title">
<input type="button" onClick="endChat()" value="Leave chat" />
</div>
<div class="outer">
<div id="msg-board"></div>
<form action="" onSubmit="submitHandler(event)">
<input type="text" id="chat-name" onChange="onChange()"
required placeholder="Chat name" />
<input id="input" autocomplete="off" required
placeholder="Type your message here" />
<input type="submit" value="Send" />
</form>
</div>
</div>
<div class="sidebar">
<div class="title">All people</div>
<div id="users" class="content"></div>
</div>
</section>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
socket.on('connection', () => {
if(!localStorage.getItem('userid')){
const userid = Date.now() + Math.round(Math.random() * 1E9).toString();
localStorage.setItem('userid', userid);
}
});
function onChange(){
const username = document.getElementById('chat-name');
if(username.value){
const obj = {
username: username.value,
userid: localStorage.getItem('userid'),
}
socket.emit('new user', obj);
}
};
socket.on('new user', (obj) => {
const msgBoard = document.getElementById('msg-board');
let element = document.createElement('div');
element.setAttribute("class", "new-user");
const msg = `${obj.username} join the conversation`;
element.textContent = msg;
msgBoard.appendChild(element);
element.scrollIntoView();
const users = document.getElementById('users');
users.innerHTML = '';
for(let key in obj.users){
element = document.createElement('div');
element.setAttribute("class", "user");
const user = obj.users[key];
element.textContent = user;
users.appendChild(element);
element.scrollIntoView();
};
});
function submitHandler(e){
e.preventDefault();
const input = document.getElementById('input');
const obj = {
userid: localStorage.getItem("userid"),
message: input.value,
};
if (input.value) {
socket.emit('chat message', obj);
input.value = '';
}
};
socket.on('chat message', function(obj){
const msgBoard = document.getElementById('msg-board');
const element = document.createElement('div');
const msg = `${obj.chatName}: ${obj.message}`;
element.textContent = msg;
msgBoard.appendChild(element);
element.scrollIntoView();
});
function endChat(){
const username = document.getElementById('chat-name');
if(username.value){
const userid = localStorage.getItem('userid');
socket.emit("user left", userid);
}
};
socket.on("user left", (obj) => {
const msgBoard = document.getElementById('msg-board');
let element = document.createElement('div');
element.setAttribute("class", "user-left");
const msg = `${obj.username} left the conversation`;
element.textContent = msg;
msgBoard.appendChild(element);
element.scrollIntoView();
const users = document.getElementById('users');
users.innerHTML = '';
for(let key in obj.users){
element = document.createElement('div');
element.setAttribute("class", "user");
const user = obj.users[key];
element.textContent = user;
users.appendChild(element);
element.scrollIntoView();
};
});
</script>
</body>
</html>
// index.js
// npm install express
// npm install socket.io
// npm install nodemon
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const path = require('path');
const { Server } = require("socket.io");
const io = new Server(server);
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.sendFile(`${__dirname}/index.html`);
});
const users = {};
io.on('connection', (socket) => {
socket.emit('connection');
socket.on('new user', (obj) => {
users[obj.userid] = obj.username;
obj.users = users;
io.emit('new user', obj);
});
socket.on('chat message', (obj) => {
obj.chatName = users[obj.userid];
io.emit('chat message', obj);
});
socket.on('user left', (userid) => {
const obj = {};
const username = JSON.stringify(users[userid]);
obj.username = JSON.parse(username);
delete users[userid];
obj.users = {...users};
io.emit('user left', obj);
socket.disconnect();
});
});
server.listen(port, () => {
console.log(`listening on *${port}`);
});