diff --git a/client/SignalExchangerClient.js b/client/SignalExchangerClient.js new file mode 100644 index 0000000..0e8a7dc --- /dev/null +++ b/client/SignalExchangerClient.js @@ -0,0 +1,114 @@ +/** + * Signal exchanger web client + * + * @author Pierre HUBERT + */ + +class SignalExchangerClient { + + /** + * Server domain + * + * @type {String} + */ + //domain; + + /** + * Server port + * + * @type {Number} + */ + //port; + + /** + * Current client ID + * + * @type {String} + */ + //clientID; + + /** + * Socket connection to the server + * + * @type {WebSocket} + */ + //socket; + + /** + * Function called in case of error + * + * @type {Function} + */ + //onError = null; + + /** + * Function called when the connection is etablished + * + * @type {Function} + */ + //onConnected = null; + + /** + * Function called when the connection to the socket is closed + * + * @type {Function} + */ + //onClosed = null; + + /** + * Construct a client instance + * + * @param {String} domain The name of the signal server + * @param {Number} port The port of the server to use + * @param {String} clientID The ID of current client + */ + constructor(domain, port, clientID) { + + //Save information + this.domain = domain, + this.port = port; + this.clientID = clientID; + + this.socket = new WebSocket("ws://" + this.domain + ":" + this.port + "/socket"); + + //Add a few events listeners + this.socket.addEventListener("open", () => { + this.serverConnected(); + + if(this.onConnected != null) + setTimeout(this.onConnected, 10); + }); + + this.socket.addEventListener("error", () => { + if(this.onError != null) + setTimeout(this.onError, 0); + }); + + this.socket.addEventListener("close", () => { + if(this.onClosed != null) + setTimeout(this.onClosed, 0); + }); + } + + /** + * Method called once the client is successfully + * connected to the client + */ + serverConnected(){ + + //Send data to the server to identificate client + this.sendData({ + client_id: this.clientID + }); + + } + + /** + * Send data to the server + * + * @param {Object} data The data to send to the server + */ + sendData(data){ + this.socket.send(JSON.stringify(data)); + } +} \ No newline at end of file diff --git a/client/server.py b/client/server.py new file mode 100755 index 0000000..a36f522 --- /dev/null +++ b/client/server.py @@ -0,0 +1,3 @@ +#!/usr/bin/env python +import SimpleHTTPServer +SimpleHTTPServer.test(); \ No newline at end of file diff --git a/client/test-client.html b/client/test-client.html new file mode 100644 index 0000000..7f5b86c --- /dev/null +++ b/client/test-client.html @@ -0,0 +1,16 @@ + + + + + + + Signal Exchanger test client + + +

Signal Exchanger test client

+ + + + + + \ No newline at end of file diff --git a/client/test-client.js b/client/test-client.js new file mode 100644 index 0000000..29eab7b --- /dev/null +++ b/client/test-client.js @@ -0,0 +1,29 @@ +/** + * Node Signal Exchanger test client + * + * @author Pierre HUBERT + */ + +const Config = { + port: 8081, + server_name: "localhost", + clientID: location.href.toString().includes("#1") ? "client-1" : "client-2" +}; + +let client = new SignalExchangerClient( + Config.server_name, + Config.port, + Config.clientID +); + +client.onConnected = function(){ + console.log("Connected to signal exchanger server."); +} + +client.onError = function() { + console.error("An error occurred with the connection to the signal exchanger server"); +} + +client.onClosed = function() { + console.log("Connection to server closed."); +} \ No newline at end of file diff --git a/index.js b/index.js index d0c4467..f1e1789 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,8 @@ const WebSocket = require("ws"); /** * Import project modules */ -const config = require("./config"); +const Config = require("./config"); +const Sockets = require("./sockets"); /** * If user tries to connect to home page, @@ -25,7 +26,22 @@ app.get("/", (req, res) => { res.send("Welcome to NodeSignalExchanger!"); }); +/** + * Start express server + */ +var server = app.listen(Config.port, () => { + console.log("Application listening on port " + Config.port); +}); -var server = app.listen(config.port, () => { - console.log("Application listening on port " + config.port); -}) \ No newline at end of file + +/** + * Handles socket connections + */ +var wss = WebSocket.Server({ + server: server, + path: "/socket" +}); + +wss.on("connection", socket => { + Sockets.addSocket(socket); +}); diff --git a/sockets.js b/sockets.js new file mode 100644 index 0000000..d801807 --- /dev/null +++ b/sockets.js @@ -0,0 +1,127 @@ +/** + * Connections sockets management + * + * @author Pierre HUBERT + */ + +let SocketsList = []; + +/** + * Send a message to the socket + * + * @param socket The target socket + * @param {Object} message The message to send to the socket + */ +function SendMessageToSocket(socket, message){ + socket.send(JSON.stringify(message)); +} + +/** + * Add a socket to the list + * + * @param {String} id The ID of the socket + * @param socket The socket to add + */ +function AddSocketToList(id, socket){ + + SocketsList.push({ + id: id, + socket: socket + }); + +} + +/** + * Remove the socket from the list + * + * @param socket Socket to remove + */ +function RemoveSocketFromList(socket){ + + for(let i = 0; i < SocketsList.length; i++){ + + if(SocketsList[i].socket == socket){ + SocketsList.splice(i, 1); + i--; + } + + } + +} + +/** + * Add a socket to the list of active sockets + * + * This method is called when the server handles a new connection + * + * @param socket + */ +exports.addSocket = function(socket){ + + console.log("New socket connection detected!"); + + /** + * This variable will contains the ID of the client + * as soon as the client will send it + */ + let client_id = false; + + /** + * We listen to socket messages + */ + socket.on("message", message => { + + //Decode message + let data; + try { + data = JSON.parse(message); + } + catch (err) { + console.error("Invalid message received from socket!"); + SendMessageToSocket(socket, { + error: "Message could not be parsed!" + }) + return; + }; + + if(!client_id){ + + //Check if the client ID was specified or not in the request + if(!data.client_id){ + SendMessageToSocket(socket, { + error: "Please specify your client ID!" + }); + return; + } + + if(typeof data.client_id != "string"){ + SendMessageToSocket(socket, { + error: "Invalid client ID specified!" + }); + return; + } + + //Save client ID + client_id = data.client_id; + AddSocketToList(client_id, socket); + console.log("New connection from client ID " + client_id); + SendMessageToSocket(socket, { + success: "Client ID successfully set." + }); + } + + else { + + + + } + }); + + + socket.on("close", () => { + if(client_id) { + console.log("Connection from " + client_id + " closed."); + RemoveSocketFromList(socket); + } + }); +} \ No newline at end of file