Created
October 28, 2018 18:54
-
-
Save AliSawari/9d6dc87c889e4de184b8b41d8a83c39d to your computer and use it in GitHub Desktop.
a small TCP-based chat room server application with Node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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