├── client.js └── server.js /client.js: -------------------------------------------------------------------------------- 1 | const { Socket } = require("net"); 2 | const readline = require("readline").createInterface({ 3 | input: process.stdin, 4 | output: process.stdout, 5 | }); 6 | 7 | const END = "END"; 8 | 9 | const error = (message) => { 10 | console.error(message); 11 | process.exit(1); 12 | }; 13 | 14 | const connect = (host, port) => { 15 | console.log(`Connecting to ${host}:${port}`); 16 | 17 | const socket = new Socket(); 18 | socket.connect({ host, port }); 19 | socket.setEncoding("utf-8"); 20 | 21 | socket.on("connect", () => { 22 | console.log("Connected"); 23 | 24 | readline.question("Choose your username: ", (username) => { 25 | socket.write(username); 26 | console.log(`Type any message to send it, type ${END} to finish`); 27 | }); 28 | 29 | readline.on("line", (message) => { 30 | socket.write(message); 31 | if (message === END) { 32 | socket.end(); 33 | } 34 | }); 35 | 36 | socket.on("data", (data) => { 37 | console.log(data); 38 | }); 39 | }); 40 | 41 | socket.on("error", (err) => error(err.message)); 42 | 43 | socket.on("close", () => { 44 | console.log("Disconnected"); 45 | process.exit(0); 46 | }); 47 | }; 48 | 49 | const main = () => { 50 | if (process.argv.length !== 4) { 51 | error(`Usage: node ${__filename} host port`); 52 | } 53 | 54 | let [, , host, port] = process.argv; 55 | if (isNaN(port)) { 56 | error(`Invalid port ${port}`); 57 | } 58 | port = Number(port); 59 | 60 | connect(host, port); 61 | }; 62 | 63 | if (module === require.main) { 64 | main(); 65 | } 66 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const { Server } = require("net"); 2 | 3 | const host = "0.0.0.0"; 4 | const END = "END"; 5 | 6 | const connections = new Map(); 7 | 8 | const error = (message) => { 9 | console.error(message); 10 | process.exit(1); 11 | }; 12 | 13 | const sendMessage = (message, origin) => { 14 | for (const socket of connections.keys()) { 15 | if (socket !== origin) { 16 | socket.write(message); 17 | } 18 | } 19 | }; 20 | 21 | const listen = (port) => { 22 | const server = new Server(); 23 | 24 | server.on("connection", (socket) => { 25 | const remoteSocket = `${socket.remoteAddress}:${socket.remotePort}`; 26 | console.log(`New connection from ${remoteSocket}`); 27 | socket.setEncoding("utf-8"); 28 | 29 | socket.on("data", (message) => { 30 | connections.values(); 31 | if (!connections.has(socket)) { 32 | console.log(`Username ${message} set for connection ${remoteSocket}`); 33 | connections.set(socket, message); 34 | } else if (message === END) { 35 | connections.delete(socket); 36 | socket.end(); 37 | } else { 38 | const fullMessage = `[${connections.get(socket)}]: ${message}`; 39 | console.log(`${remoteSocket} -> ${fullMessage}`); 40 | sendMessage(fullMessage, socket); 41 | } 42 | }); 43 | 44 | socket.on("error", (err) => console.error(err)); 45 | 46 | socket.on("close", () => { 47 | console.log(`Connection with ${remoteSocket} closed`); 48 | }); 49 | }); 50 | 51 | server.listen({ port, host }, () => { 52 | console.log("Listening on port 8000"); 53 | }); 54 | 55 | server.on("error", (err) => error(err.message)); 56 | }; 57 | 58 | const main = () => { 59 | if (process.argv.length !== 3) { 60 | error(`Usage: node ${__filename} port`); 61 | } 62 | 63 | let port = process.argv[2]; 64 | if (isNaN(port)) { 65 | error(`Invalid port ${port}`); 66 | } 67 | 68 | port = Number(port); 69 | 70 | listen(port); 71 | }; 72 | 73 | if (require.main === module) { 74 | main(); 75 | } 76 | --------------------------------------------------------------------------------