Last active
December 14, 2016 08:15
-
-
Save yogurt1/fe53e27bca3ad92894a3db96090b4099 to your computer and use it in GitHub Desktop.
Chat in pure Node.js at backend and Vanilla.js at frontend
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
var http = require("http"); | |
var msgs = []; // All messages array | |
var subscribers = []; // All subscribers array | |
var PORT = process.env.PORT || 8080; | |
// Create HTTP server | |
var server = http.createServer(function(req, res) { | |
// Small router | |
switch(req.url) { | |
case "/": | |
// If got index request send chat html page | |
res.writeHead(200, {"Content-Type":"text/html"}); | |
return res.end(html()); | |
default: | |
// If request is unknown send 404 | |
res.writeHead(404) | |
return res.end() | |
case "/subscribe": return subscribe(req, res); | |
case "/publish": return publish(req, res); | |
} | |
}).listen(PORT); | |
// Subscribe client for server-sent events | |
function subscribe(req, res) { | |
// Get index of subscriber | |
var id = subscribers.push(res) - 1 | |
// Send HTTP headers | |
res.writeHead(200, { | |
"Content-Type": "text/event-stream", | |
"Cache-Control": "no-cache" | |
}); | |
// Remove client from array | |
req.on("close", function() { | |
// unsubscribe | |
subscribers.splice(id, 1) | |
}); | |
} | |
// Publish message to all clients | |
function publish(req, res) { | |
req.on("data", function(data) { | |
// Format message | |
var msg = formatMessage(data.toString(), | |
req.socket.remoteAddress, | |
req.socket.remotePort) | |
msgs.push(msg) | |
subscribers.forEach(function(s) { | |
s.write("data: " + msg + '\n\n'); | |
}) | |
}); | |
} | |
function formatMessage(msg, remoteAddress, remotePort) { | |
var date = new Date(); | |
var hour = date.getHours(); | |
hour = (hour < 10 ? "0" : "") + hour; | |
var min = date.getMinutes(); | |
min = (min < 10 ? "0" : "") + min; | |
var sec = date.getSeconds(); | |
sec = (sec < 10 ? "0" : "") + sec; | |
// var year = date.getFullYear(); | |
// var mont = date.getMonth() + 1; | |
// month = (month < 10 ? "0" : "") + month; | |
// var day = date.getDate(); | |
// day = (day < 10 ? "0" : "") + day; | |
var formattedDate = hour + ":" + min + ":" + sec; | |
var meta = " - (" + remoteAddress + ":" + remotePort + "): "; | |
return formattedDate + meta + msg | |
} | |
// HTML template | |
function html(){ | |
return "" | |
+ "<!DOCTYPE html><html><head></head><body>" | |
+ "<textarea id=\"msg\" rows=\"3\" cols=\"100\"></textarea><br>" | |
+ "<input type=\"button\" id=\"send\" value=\"Send\"><br>" | |
+ "<textarea disabled id=\"chat\" rows=\"30\" cols=\"100\"></textarea>" | |
+ "<script>" | |
+ "var chat = document.getElementById(\"chat\");/* Inject messages to document */" | |
+ "var msgs = " + JSON.stringify(msgs) + ";" | |
+ "chat.innerHTML = msgs.join('\\n');" | |
+ "/* Subscribe */" | |
+ "var es = new EventSource(\"subscribe\");" | |
+ "es.onmessage = function(msg) {" | |
+ "chat.innerHTML += \"\\n\";" | |
+ "chat.innerHTML += msg.data;" | |
+ "}" | |
+ "/* Publish */\n" | |
+ "document.getElementById(\"send\")" | |
+ ".addEventListener(\"click\", function() {" | |
+ "var textarea = document.getElementById(\"msg\");" | |
+ "var msg = textarea.value;" | |
+ "if (msg.length) {" | |
+ "var xhr = new XMLHttpRequest();" | |
+ "xhr.open(\"POST\", \"/publish\", true);" | |
+ "xhr.setRequestHeader(\"Content-Type\", \"text/plain\");" | |
+ "xhr.send(msg);" | |
+ "}" | |
+ "textarea.value = \"\";" | |
+ "textarea.focus();" | |
+ "});" | |
+ "</script></body></html>"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment