Skip to content

Instantly share code, notes, and snippets.

@AliSawari
Created October 28, 2018 18:54
Show Gist options
  • Save AliSawari/9d6dc87c889e4de184b8b41d8a83c39d to your computer and use it in GitHub Desktop.
Save AliSawari/9d6dc87c889e4de184b8b41d8a83c39d to your computer and use it in GitHub Desktop.
a small TCP-based chat room server application with Node.js
// including the net module
const net = require('net');
// clients array
let clients = [];
// a nice little logger with a time stamp
// loggin messages for both server and Client
function logger(m){
let d = new Date().toLocaleString();
let t = `${d} - ${m.toString()}\n`;
console.log(t);
return t;
}
// how many alive ?
const alive = () => `Server: ${clients.length} member(s) currently online`;
// the server sends greeting for each new user
function serverGreet(cli){
cli.write(logger('Server: Welcome'));
cli.write(logger(alive()));
cli.write(logger('Server: Say Hello to everyone :)'));
cli.write(logger('Hit Ctrl + C to exit'));
cli.write(' ----- MrGhost TCP RoOm-------- \n\n');
}
// broadcasting messages to all users
function broadcast(msg){
clients.map(c => {
c.write(logger(msg));
});
}
// sending messages to all, but yourself
// if you're online alone, log your messages to the server
// of course I wanna see everything in my TCP chat room :)
function send2All(id, msg){
clients.map(c => {
if(c.id !== id){
c.write(logger(`Client ${id}: ${msg}`));
} else if(clients.length === 1) {
logger(`Client ${id}: ${msg}`);
}
});
}
// add a client to the list and broadcast it
function addCli(cli){
clients.push(cli);
broadcast(`Server: Client ${cli.id} Joined.`);
}
// removes a client and broadcast it
// if no one's online, log it to the server
function remCli(cli){
clients.splice(clients.indexOf(cli), 1);
if(clients.length){
broadcast(`Server: Client ${cli.id} left.`);
broadcast(alive());
} else {
logger(`Client ${cli.id} Left.`);
logger(alive());
}
}
// creating the TCP Server
const tcpServer = net.createServer(cli => {
// giving a unique ID to each User
// notice how I didn't simply used cli.id = client.length + 1
// because this method will cause duplicate IDs when the first users leave. see below
// client number 1 joins, id is 1
// client number 2 joins, id is 2
// client number 1 leaves, so client.length will equal 1 again
// client number 3 joins, but the id will be resolved as 2 because id = client.length + 1
// so we will have two clients with the same id!!
// the method below tries to find the last element in the array and get the id from that element
// if there is a 'last child' it will take his Id and increment it by 1
// if there isn't anything, we will have our first user with the ID of 1
cli.id = clients[clients.length - 1].id ? clients[clients.length - 1].id + 1 : 1
// adding the new client
addCli(cli);
// sending the greetings messages by server
serverGreet(cli);
// listening for any type of data and send it to all
// see send2All() on line 38
cli.on('data', data => send2All(cli.id, data.toString() ) );
// if the connection from the client closes, remove the client from the clients list
cli.on('close', () => remCli(cli));
});
// listening for Errors
tcpServer.on('error', err => {
throw err;
});
// starting the TCP Server
tcpServer.listen(3000, () => {
console.log('TCP Server started on port 3000');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment