//#!/usr/bin/env node // // WebSocket chat server // Implemented using Node.js // // Requires the websocket module. // // WebSocket and WebRTC based multi-user chat sample with two-way video // calling, including use of TURN if applicable or necessary. // // This file contains the JavaScript code that implements the server-side // functionality of the chat system, including user ID management, message // reflection, and routing of private messages, including support for // sending through unknown JSON objects to support custom apps and signaling // for WebRTC. // // Requires Node.js and the websocket module (WebSocket-Node): // // - http://nodejs.org/ // - https://github.com/theturtle32/WebSocket-Node // // To read about how this sample works: http://bit.ly/webrtc-from-chat // // Any copyright is dedicated to the Public Domain. // http://creativecommons.org/publicdomain/zero/1.0/ "use strict"; var http = require('http'); var https = require('https'); var fs = require('fs'); var WebSocketServer = require('websocket').server; // Pathnames of the SSL key and certificate files to use for // HTTPS connections. const keyFilePath = "/etc/letsencrypt/live/bebra.team/privkey.pem"; // const certFilePath = "/etc/letsencrypt/live/bebra.ateam/cert.pem"; const certFilePath = "/etc/letsencrypt/live/bebra.team/fullchain.pem"; // Used for managing the text chat user list. var connectionArray = []; var nextID = Date.now(); var appendToMakeUnique = 1; // Output logging information to console function log(text) { var time = new Date(); console.log("[" + time.toLocaleTimeString() + "] " + text); } // If you want to implement support for blocking specific origins, this is // where you do it. Just return false to refuse WebSocket connections given // the specified origin. function originIsAllowed(origin) { return true; // We will accept all connections } // Scans the list of users and see if the specified name is unique. If it is, // return true. Otherwise, returns false. We want all users to have unique // names. function isUsernameUnique(name) { var isUnique = true; var i; for (i=0; i]+)>)/ig, ""); break; // Username change case "username": var nameChanged = false; var origName = msg.name; // Ensure the name is unique by appending a number to it // if it's not; keep trying that until it works. while (!isUsernameUnique(msg.name)) { msg.name = origName + appendToMakeUnique; appendToMakeUnique++; nameChanged = true; } // If the name had to be changed, we send a "rejectusername" // message back to the user so they know their name has been // altered by the server. if (nameChanged) { var changeMsg = { id: msg.id, type: "rejectusername", name: msg.name }; connect.sendUTF(JSON.stringify(changeMsg)); } // Set this connection's final username and send out the // updated user list to all users. Yeah, we're sending a full // list instead of just updating. It's horribly inefficient // but this is a demo. Don't do this in a real app. connect.username = msg.name; sendUserListToAll(); sendToClients = false; // We already sent the proper responses break; } // Convert the revised message back to JSON and send it out // to the specified client or all clients, as appropriate. We // pass through any messages not specifically handled // in the select block above. This allows the clients to // exchange signaling and other control objects unimpeded. if (sendToClients) { var msgString = JSON.stringify(msg); var i; // If the message specifies a target username, only send the // message to them. Otherwise, send it to every user. if (msg.target && msg.target !== undefined && msg.target.length !== 0) { sendToOneUser(msg.target, msgString); } else { for (i=0; i