From b2c4859226aec4e5d26aad21329cc5ea1fb02b79 Mon Sep 17 00:00:00 2001 From: davidovski Date: Thu, 8 Jul 2021 19:26:10 +0100 Subject: First commit to git --- README.md | 3 ++ dist/default.css | 57 +++++++++++++++++++++++++++++++++++ dist/index.html | 21 +++++++++++++ dist/index.js | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++ dist/test/index.html | 3 ++ main.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 ++++ 7 files changed, 250 insertions(+) create mode 100644 README.md create mode 100644 dist/default.css create mode 100644 dist/index.html create mode 100644 dist/index.js create mode 100644 dist/test/index.html create mode 100644 main.js create mode 100644 package.json diff --git a/README.md b/README.md new file mode 100644 index 0000000..d64ce72 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Chatroom + +This is an example For creating a simple web socket chatroom server with a webclient diff --git a/dist/default.css b/dist/default.css new file mode 100644 index 0000000..933b93a --- /dev/null +++ b/dist/default.css @@ -0,0 +1,57 @@ +body { + color: white; + background-color: #222; + font-family: Arial, sans-serif; + overflow: hidden; +} + +.header { + height: 10%; +} +.main { + height: 85%; +} + +.footer { + float: bottom; + height:5% +} + +#messages { + height: 100%; + overflow-y: scroll; + overflow-x: auto; + position: relative; + bottom: 0; +} + +#msgbox { + width: 100%; + height: 100%; +} + +input { + border: 1px solid #45d; + background-color: #45b; + color: white; +} +input:focus { + border: 1px solid #000; + +} + +::-webkit-scrollbar { + width: 10px; +} + +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0); +} + +::-webkit-scrollbar-thumb { + background: #888; +} + +::-webkit-scrollbar-thumb:hover { + background: #555; +} diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..c2bcad6 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,21 @@ + + chatroom + + + + + + +
+

welcome to discörd

+ + +
+
+
+
+
+ + diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..2ad7b15 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,85 @@ +document.addEventListener("DOMContentLoaded", () => { + + // Read parameters in the url and find a nickname from them + const params = new URLSearchParams(window.location.search); + var nick = params.get("nick"); + // preload the nickname into the nickname input box + if (nick) { + var nickbox = document.getElementById("nickbox"); + nickbox.value = nick; + } + + // initialise the websocket connection + const url = `ws://${window.location.hostname}:8081`; + const connection = new WebSocket(url); + + // define functions listening to the websocket + connection.onopen = () => { + + // estimate how many lines should be requested from the client + var lines = Math.round(window.innerHeight / 12); + // send the initial "join" message from the client, with an initial nickname and how many messages should be preloaded + connection.send(JSON.stringify({ + event: "join", + nickname: nick, + lines: lines + })); + } + + // define a listener for errors, to be printed to the console + connection.onerror = error => { + console.log(`WebSocket error: ${error}`); + } + + // define a listener for messages + connection.onmessage = (ev) => { + // parse the message as a json object + var data = JSON.parse(ev.data); + + // If the message is of type "message", we can add it to the screen + if (data.event == "message"){ + addMessage(data.content, data.nickname); + } + } + + // display messages on the screen for the user + function addMessage(content, sender) { + + // Find the "messages" box in the document + var messagesElement = document.getElementById("messages"); + + // create a new message and add it as a child to the messagesElement + var newMessage = document.createElement("div"); + newMessage.innerText = `${sender}: ${content}`; + messagesElement.appendChild(newMessage); + + // update the scroll, so that the client has the newest message visible + messagesElement.scrollTop = messagesElement.scrollHeight; + } + + // send a message to the webserver + function sendMessage(msg) { + // check the nickname box for a value + nick = document.getElementById("nickbox").value; + + // Send a json object to the websocket + connection.send(JSON.stringify({ + content: msg, + nickname: nick, + event: "message" + })); + } + + var inputBox = document.getElementById("msgbox"); + // prefocus the input box when the page is loaded + inputBox.focus(); + // add event listener for enter key on input box + inputBox.addEventListener("keyup", ev => { + if (event.keyCode == 13) { + event.preventDefault(); + sendMessage(inputBox.value); + inputBox.value = ""; + } + }) +}); + diff --git a/dist/test/index.html b/dist/test/index.html new file mode 100644 index 0000000..8c62610 --- /dev/null +++ b/dist/test/index.html @@ -0,0 +1,3 @@ + +

ctest

+ diff --git a/main.js b/main.js new file mode 100644 index 0000000..a849dd4 --- /dev/null +++ b/main.js @@ -0,0 +1,76 @@ +const http = require("http"); +const fs = require("fs"); +const path = require("path"); +const url = require("url"); +const websocket = require("ws"); + +const static_content = __dirname + "/dist/"; + +// Create an array to store messages in +var log = [] + +// Initialise a simple http server to serve any static files +http.createServer((req, res) => { + + // normalise path name to stay within a normal directory + var requestUrl = url.parse(req.url); + var fsPath = static_content + path.normalize(requestUrl.pathname); + + // automatically return the index of a directory, if its been selected + if (fs.statSync(fsPath).isDirectory()) + fsPath += fsPath.endsWith("/") ? "index.html" : "/index.html"; + + // read and send the file + fs.readFile(fsPath, (err, data) => { + if (err) { + res.writeHead(404); + res.end(JSON.stringify(err)) + } else { + res.writeHead(200); + res.end(data); + } + }); +}).listen(8080); + +// create websocket: client tracking allows us to get a set of clients so that we can send messages to each client once they appear +const wss = new websocket.Server({port : 8081, clientTracking: true}); + +wss.on("connection", ws => { + // predefine a user nickname + var nick = "anon" + wss.clients.size + + ws.on("message", msg => { + var data = JSON.parse(msg); + + // Ensure that nickname requirements are met before setting client's nick + if (data.nickname && data.nickname.length < 24 && data.nickname.length > 0) nick = data.nickname; + + switch data.event { + case "join": + // send the client the requested number of messages before joining + if (data.lines) log.slice(0-data.lines).forEach(l => ws.send(l)) + break; + case "message": + // ensure that the message length requirements are met correctly + if (data.content.length < 128 && data.content.length > 0) { + + // recreate the message object to be sent + message = JSON.stringify({ + event: "message", + content: data.content, + nickname: nick + }); + + // send the message to the log array first + log.push(message); + + // propogate the message to all connected clients + wss.clients.forEach(c => { + c.send(message); + }) + } + break; + } + + }); +}) diff --git a/package.json b/package.json new file mode 100644 index 0000000..779bfec --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "ws": "^7.5.2" + } +} -- cgit v1.2.1