Last active
December 30, 2015 10:39
-
-
Save mattrasband/7817596 to your computer and use it in GitHub Desktop.
A basic chat server written in Node.js. Tried to improve on the ones that are currently floating around. Note: Not great from telnet on Windows - works fine on *nix.
This file contains hidden or 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
/* | |
File: ChatServer.js | |
Author: Nerdwaller | |
Description: | |
A fairly simple chat server using Node.js. | |
It takes several pieces from other scripts, adds some original pieces, and additional functionality. | |
*/ | |
var net = require("net"); | |
// Server Config | |
var SERVER = { | |
name : "Node.js Simple Chat Server", | |
port : 8000, | |
host : "127.0.0.1", | |
prmpt: "> " | |
}; | |
// Class For Client Sockets | |
function Socket(socket) { | |
this.uname = null; // Username | |
this.id = null; // Unique ID (IP:PORT) | |
this.socket = socket; // Socket Object | |
this.buffer = ""; // Buffer of Text | |
} | |
// Proto for removing items from arrays. | |
Array.prototype.remove = function(e) { | |
for (var i = 0; i < this.length; i++) { | |
if (e == this[i]) { | |
return this.splice(i, 1); | |
} | |
} | |
}; | |
// Proto to check for an object in the array (Searches by member variable) | |
Array.prototype.exists = function(attrib, value) { | |
var found = false; | |
this.forEach(function(c) { | |
if (c.hasOwnProperty(attrib) && c[attrib] == value) { | |
found = true; | |
} | |
}); | |
return found; | |
}; | |
// List of connected clients | |
var CLIENTS = []; | |
// Create the server and add listeners for events. | |
var srv = net.createServer(function(socket) { | |
// CTOR (Client Connect) | |
var client = new Socket(socket); | |
CLIENTS.push(client); | |
socket.setEncoding("utf8"); | |
client.id = socket.remoteAddress + ':' + socket.remotePort; | |
client.uname = client.id; // Set a default username | |
// Report to the server and other clients that someone has connected. | |
console.log("+" + client.id + ", " + CLIENTS.length + " connected clients."); | |
socket.write("Welcome to " + SERVER.name + ".\r\n"); | |
socket.write(SERVER.prmpt); | |
CLIENTS.forEach(function(c) { | |
if (c != client) { | |
c.socket.write("\r<srv>: " + client.id + " has joined.\r\n"); | |
c.socket.write(SERVER.prmpt); | |
} | |
}); | |
// DTOR (Client Disconnect) | |
socket.addListener('end', function() { | |
CLIENTS.remove(client); | |
console.log("-" + client.id + ", " + CLIENTS.length + " connected clients."); | |
CLIENTS.forEach(function(c) { | |
c.socket.write(client.id + " has left.\r\n"); | |
c.socket.write(SERVER.prmpt); | |
}); | |
socket.end(); | |
}); | |
// Handle Received Data | |
socket.addListener("data", function(d) { | |
client.buffer += d; | |
if (client.buffer[client.buffer.length - 1] == "\n") { | |
if (client.buffer.match(/^!.*/)) { // A command always takes form !command | |
var cmd = client.buffer.split(" ")[0]; | |
var params = client.buffer.split(" "); | |
cmd = cmd.replace("!", "").trim(); | |
switch(cmd) { | |
case "quit": | |
client.socket.end(); | |
return; | |
case "set": | |
switch(params[1]) { | |
case "name": | |
if (!CLIENTS.exists("uname", params[2].trim())) { | |
client.uname = params[2].trim(); | |
} | |
else { | |
client.socket.write("Username already taken.\r\n"); | |
} | |
break; | |
default: | |
client.socket.write("Valid !set commands:\r\n\t!set name uname\r\n"); | |
} | |
break; | |
default: | |
client.socket.write("Invalid command.\r\n"); | |
} | |
} | |
else { | |
CLIENTS.forEach(function(c) { | |
if (c != client) { | |
c.socket.write("\r" + client.uname + ": " + client.buffer); | |
c.socket.write(SERVER.prmpt); | |
} | |
}); | |
} | |
client.buffer = ""; | |
client.socket.write(SERVER.prmpt); | |
} | |
}); | |
// Interrupt Handlers | |
process.on('SIGINT', function() { | |
console.log("SIGINT detected, shutting down server and disconnecting all clients (" + CLIENTS.length + ")."); | |
CLIENTS.forEach(function(c) { | |
c.socket.write("Server is shutting down, your connection will be closed."); | |
c.socket.end(); | |
}); | |
process.exit(); | |
}); | |
}); | |
srv.listen(SERVER.port, SERVER.host); | |
console.log("Server is running on " + SERVER.host + ":" + SERVER.port); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment