From c48fc95f6883482cd1e569dfe9d5029f39c35809 Mon Sep 17 00:00:00 2001 From: Muaz Khan Date: Thu, 10 Jan 2019 10:14:46 +0500 Subject: [PATCH] Released version 1.3.1 with breaking new changes. Check readme.md --- README.md | 35 ++- bower.json | 2 +- node_scripts/Scalable-Broadcast.js | 15 +- node_scripts/Signaling-Server.js | 121 +++----- node_scripts/after-http-listen.js | 48 ++++ node_scripts/before-http-listen.js | 91 ++++++ node_scripts/get-values-from-config-json.js | 8 +- node_scripts/index.js | 294 +------------------- node_scripts/pushLogs.js | 8 +- package.json | 2 +- server.js | 123 +++++++- 11 files changed, 362 insertions(+), 385 deletions(-) create mode 100644 node_scripts/after-http-listen.js create mode 100644 node_scripts/before-http-listen.js diff --git a/README.md b/README.md index 17b5f68..9ee04c8 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,27 @@ [![npm](https://img.shields.io/npm/v/rtcmulticonnection-server.svg)](https://npmjs.org/package/rtcmulticonnection-server) [![downloads](https://img.shields.io/npm/dm/rtcmulticonnection-server.svg)](https://npmjs.org/package/rtcmulticonnection-server) -**Installation Guide:** https://github.com/muaz-khan/RTCMultiConnection-Server/wiki +> Since version `1.3.1`: now `rtcmulticonnection-server` does not creates any HTTP server. +> +> Now you need to use this: `require('rtcmulticonnection-server').addSocket(socket)` where `socket` is your socket.io connection object. +> +> It means that now you can integrate `rtcmulticonnection-server` inside any socket.io application or expressjsj/angular frameworks. -Free servers: +```sh +npm install rtcmulticonnection-server + +# either +node server.js --help + +# or +require('rtcmulticonnection-server').addSocket(socket); +``` + +**Installation Guide:** + +* https://github.com/muaz-khan/RTCMultiConnection-Server/wiki + +## Free socket.io servers ```javascript connectin.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/'; @@ -19,11 +37,22 @@ connectin.socketURL = 'https://webrtcweb.com:9002/'; ## Integrate inside nodejs applications +```javascript +const ioServer = require('socket.io'); +const RTCMultiConnectionServer = require('rtcmulticonnection-server'); + +ioServer(httpApp).on('connection', function(socket) { + RTCMultiConnectionServer.addSocket(socket); +}); +``` + +For more information: + * https://github.com/muaz-khan/RTCMultiConnection-Server/wiki/Integrate-inside-nodejs-applications ## Demos -* https://github.com/muaz-khan/RTCMultiConnection +* https://rtcmulticonnection.herokuapp.com/demos/ ## License diff --git a/bower.json b/bower.json index 055b069..a0a0af0 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "rtcmulticonnection-server", "description": "RTCMultiConnection socket.io server", - "version": "1.3.0", + "version": "1.3.1", "authors": [ { "name": "Muaz Khan", diff --git a/node_scripts/Scalable-Broadcast.js b/node_scripts/Scalable-Broadcast.js index 46d76dd..649487f 100644 --- a/node_scripts/Scalable-Broadcast.js +++ b/node_scripts/Scalable-Broadcast.js @@ -7,7 +7,7 @@ var pushLogs = require('./pushLogs.js'); var users = {}; -module.exports = exports = function(root, socket, maxRelayLimitPerUser) { +module.exports = exports = function(config, socket, maxRelayLimitPerUser) { try { maxRelayLimitPerUser = parseInt(maxRelayLimitPerUser) || 2; } catch (e) { @@ -73,7 +73,7 @@ module.exports = exports = function(root, socket, maxRelayLimitPerUser) { socket.emit('logs', 'You <' + user.userid + '> are now serving the broadcast.'); } } catch (e) { - pushLogs(root, 'join-broadcast', e); + pushLogs(config, 'join-broadcast', e); } }); @@ -98,7 +98,7 @@ module.exports = exports = function(root, socket, maxRelayLimitPerUser) { try { callback(!!users[userid] && users[userid].isBroadcastInitiator === true); } catch (e) { - pushLogs(root, 'check-broadcast-presence', e); + pushLogs(config, 'check-broadcast-presence', e); } }); @@ -193,7 +193,7 @@ module.exports = exports = function(root, socket, maxRelayLimitPerUser) { delete users[socket.userid]; } catch (e) { - pushLogs(root, 'scalable-broadcast-disconnect', e); + pushLogs(config, 'scalable-broadcast-disconnect', e); } }; @@ -248,7 +248,7 @@ function askNestedUsersToRejoin(relayReceivers) { }); } catch (e) { - pushLogs(root, 'askNestedUsersToRejoin', e); + pushLogs(config, 'askNestedUsersToRejoin', e); } } @@ -278,7 +278,8 @@ function getFirstAvailableBroadcaster(broadcastId, maxRelayLimitPerUser) { if (userFound) { continue; } else if (user.broadcastId === broadcastId) { - if (!user.relayReceivers.length && user.canRelay === true) { + // if (!user.relayReceivers.length && user.canRelay === true) { + if (user.relayReceivers.length < maxRelayLimitPerUser && user.canRelay === true) { userFound = user; } } @@ -292,6 +293,6 @@ function getFirstAvailableBroadcaster(broadcastId, maxRelayLimitPerUser) { // so that each relaying user can distribute the bandwidth return broadcastInitiator; } catch (e) { - pushLogs(root, 'getFirstAvailableBroadcaster', e); + pushLogs(config, 'getFirstAvailableBroadcaster', e); } } diff --git a/node_scripts/Signaling-Server.js b/node_scripts/Signaling-Server.js index 0c61ec7..f4c9f9d 100644 --- a/node_scripts/Signaling-Server.js +++ b/node_scripts/Signaling-Server.js @@ -18,35 +18,10 @@ var CONST_STRINGS = require('./CONST_STRINGS.js'); var isAdminAuthorized = require('./verify-admin.js'); -module.exports = exports = function(root, app, socketCallback) { - socketCallback = socketCallback || function() {}; - app.config = app.config || {}; +module.exports = exports = function(socket, config) { + config = config || {}; - if (!!app.listen) { - var io = require('socket.io'); - - try { - // use latest socket.io - io = io(app); - io.on('connection', onConnection); - } catch (e) { - // otherwise fallback - io = io.listen(app, { - log: false, - origins: '*:*' - }); - - io.set('transports', [ - 'websocket', - 'xhr-polling', - 'jsonp-polling' - ]); - - io.sockets.on('connection', onConnection); - } - } else { - onConnection(app); - } + onConnection(socket); // to secure your socket.io usage: (via: docs/tips-tricks.md) // io.set('origins', 'https://domain.com'); @@ -77,14 +52,14 @@ module.exports = exports = function(root, app, socketCallback) { socketCustomEvent: params.socketCustomEvent || '' }; } catch (e) { - pushLogs(root, 'appendUser', e); + pushLogs(config, 'appendUser', e); } sendToAdmin(); } function sendToAdmin(all) { - if(app.config.enableAdmin !== true) { + if(config.enableAdmin !== true) { return; } @@ -92,7 +67,7 @@ module.exports = exports = function(root, app, socketCallback) { if (adminSocket) { var users = []; // temporarily disabled - app.config.enableAdmin === true && Object.keys(listOfUsers).forEach(function(userid) { + config.enableAdmin === true && Object.keys(listOfUsers).forEach(function(userid) { try { var item = listOfUsers[userid]; if (!item) return; // maybe user just left? @@ -111,7 +86,7 @@ module.exports = exports = function(root, app, socketCallback) { connectedWith: Object.keys(item.connectedWith) }); } catch (e) { - pushLogs(root, 'admin.user-looper', e); + pushLogs(config, 'admin.user-looper', e); } }); @@ -128,17 +103,17 @@ module.exports = exports = function(root, app, socketCallback) { }); } } catch (e) { - pushLogs(root, 'admin', e); + pushLogs(config, 'admin', e); } } function handleAdminSocket(socket, params) { - if(app.config.enableAdmin !== true || !params.adminUserName || !params.adminPassword) { + if(config.enableAdmin !== true || !params.adminUserName || !params.adminPassword) { socket.emit('admin', { error: 'Please pass "adminUserName" and "adminPassword" via socket.io parameters.' }); - pushLogs(root, 'invalid-admin', { + pushLogs(config, 'invalid-admin', { message: CONST_STRINGS.INVALID_ADMIN_CREDENTIAL, stack: 'name: ' + params.adminUserName + '\n' + 'password: ' + params.adminPassword }); @@ -147,12 +122,12 @@ module.exports = exports = function(root, app, socketCallback) { return; } - if (!app.config || !isAdminAuthorized(params, app.config)) { + if (!isAdminAuthorized(params, config)) { socket.emit('admin', { error: 'Invalid admin username or password.' }); - pushLogs(root, 'invalid-admin', { + pushLogs(config, 'invalid-admin', { message: CONST_STRINGS.INVALID_ADMIN_CREDENTIAL, stack: 'name: ' + params.adminUserName + '\n' + 'password: ' + params.adminPassword }); @@ -167,12 +142,12 @@ module.exports = exports = function(root, app, socketCallback) { adminSocket = socket; socket.on('admin', function(message, callback) { - if (!app.config || !isAdminAuthorized(params, app.config)) { + if (!isAdminAuthorized(params, config)) { socket.emit('admin', { error: 'Invalid admin username or password.' }); - pushLogs(root, 'invalid-admin', { + pushLogs(config, 'invalid-admin', { message: CONST_STRINGS.INVALID_ADMIN_CREDENTIAL, stack: 'name: ' + params.adminUserName + '\n' + 'password: ' + params.adminPassword }); @@ -198,13 +173,13 @@ module.exports = exports = function(root, app, socketCallback) { }); } } catch (e) { - pushLogs(root, 'userinfo', e); + pushLogs(config, 'userinfo', e); } } if (message.clearLogs === true) { // last callback parameter will force to clear logs - pushLogs(root, '', '', callback); + pushLogs(config, '', '', callback); } if (message.deleteUser === true) { @@ -222,7 +197,7 @@ module.exports = exports = function(root, app, socketCallback) { // delete listOfUsers[message.userid]; callback(true); } catch (e) { - pushLogs(root, 'deleteUser', e); + pushLogs(config, 'deleteUser', e); callback(false); } } @@ -243,7 +218,7 @@ module.exports = exports = function(root, app, socketCallback) { } callback(true); } catch (e) { - pushLogs(root, 'deleteRoom', e); + pushLogs(config, 'deleteRoom', e); callback(false); } } @@ -292,9 +267,9 @@ module.exports = exports = function(root, app, socketCallback) { // path to scalable broadcast script must be accurate ScalableBroadcast = require('./Scalable-Broadcast.js'); } - ScalableBroadcast._ = ScalableBroadcast(root, socket, params.maxRelayLimitPerUser); + ScalableBroadcast._ = ScalableBroadcast(config, socket, params.maxRelayLimitPerUser); } catch (e) { - pushLogs(root, 'ScalableBroadcast', e); + pushLogs(config, 'ScalableBroadcast', e); } } @@ -325,11 +300,11 @@ module.exports = exports = function(root, app, socketCallback) { try { listOfUsers[user].socket.emit('extra-data-updated', socket.userid, extra); } catch (e) { - pushLogs(root, 'extra-data-updated.connectedWith', e); + pushLogs(config, 'extra-data-updated.connectedWith', e); } } } catch (e) { - pushLogs(root, 'extra-data-updated.connectedWith', e); + pushLogs(config, 'extra-data-updated.connectedWith', e); } // sent alert to all room participants @@ -354,14 +329,14 @@ module.exports = exports = function(root, app, socketCallback) { user.socket.emit('extra-data-updated', socket.userid, extra); } catch (e) { - pushLogs(root, 'extra-data-updated.participants', e); + pushLogs(config, 'extra-data-updated.participants', e); } }); } sendToAdmin(); } catch (e) { - pushLogs(root, 'extra-data-updated', e); + pushLogs(config, 'extra-data-updated', e); } }); @@ -407,7 +382,7 @@ module.exports = exports = function(root, app, socketCallback) { callback(); } catch (e) { - pushLogs(root, 'changed-uuid', e); + pushLogs(config, 'changed-uuid', e); } }); @@ -430,7 +405,7 @@ module.exports = exports = function(root, app, socketCallback) { callback(false, roomid, CONST_STRINGS.ROOM_PERMISSION_DENIED); } } catch (e) { - pushLogs(root, 'set-password', e); + pushLogs(config, 'set-password', e); } }); @@ -451,7 +426,7 @@ module.exports = exports = function(root, app, socketCallback) { } callback(); } catch (e) { - pushLogs(root, 'disconnect-with', e); + pushLogs(config, 'disconnect-with', e); } }); @@ -476,7 +451,7 @@ module.exports = exports = function(root, app, socketCallback) { callback(true); } catch (e) { - pushLogs(root, 'close-entire-session', e); + pushLogs(config, 'close-entire-session', e); } }); @@ -503,7 +478,7 @@ module.exports = exports = function(root, app, socketCallback) { callback(true, roomid, extra); } } catch (e) { - pushLogs(root, 'check-presence', e); + pushLogs(config, 'check-presence', e); } }); @@ -547,7 +522,7 @@ module.exports = exports = function(root, app, socketCallback) { sendToAdmin(); } } catch (e) { - pushLogs(root, 'onMessageCallback', e); + pushLogs(config, 'onMessageCallback', e); } } @@ -595,7 +570,7 @@ module.exports = exports = function(root, app, socketCallback) { }); } } catch (e) { - pushLogs(root, 'joinARoom', e); + pushLogs(config, 'joinARoom', e); } sendToAdmin(); @@ -622,7 +597,7 @@ module.exports = exports = function(root, app, socketCallback) { if (listOfRooms[roomid].participants.indexOf(userid) !== -1) return; listOfRooms[roomid].participants.push(userid); } catch (e) { - pushLogs(root, 'appendToRoom', e); + pushLogs(config, 'appendToRoom', e); } } @@ -676,7 +651,7 @@ module.exports = exports = function(root, app, socketCallback) { } } } catch (e) { - pushLogs(root, 'closeOrShiftRoom', e); + pushLogs(config, 'closeOrShiftRoom', e); } } @@ -756,7 +731,7 @@ module.exports = exports = function(root, app, socketCallback) { onMessageCallback(message); } catch (e) { - pushLogs(root, 'on-socketMessageEvent', e); + pushLogs(config, 'on-socketMessageEvent', e); } }); @@ -860,7 +835,7 @@ module.exports = exports = function(root, app, socketCallback) { autoCloseEntireSession = true; } } catch (e) { - pushLogs(root, 'open-room', e); + pushLogs(config, 'open-room', e); } // append this user into participants list @@ -892,7 +867,7 @@ module.exports = exports = function(root, app, socketCallback) { listOfRooms[arg.sessionid].password = arg.password; } } catch (e) { - pushLogs(root, 'open-room.password', e); + pushLogs(config, 'open-room.password', e); } } @@ -906,7 +881,7 @@ module.exports = exports = function(root, app, socketCallback) { extra: arg.extra }; } catch (e) { - pushLogs(root, 'open-room', e); + pushLogs(config, 'open-room', e); } sendToAdmin(); @@ -914,7 +889,7 @@ module.exports = exports = function(root, app, socketCallback) { try { callback(true); } catch (e) { - pushLogs(root, 'open-room', e); + pushLogs(config, 'open-room', e); } }); @@ -943,7 +918,7 @@ module.exports = exports = function(root, app, socketCallback) { } listOfUsers[socket.userid].extra = arg.extra; } catch (e) { - pushLogs(root, 'join-room', e); + pushLogs(config, 'join-room', e); } try { @@ -952,7 +927,7 @@ module.exports = exports = function(root, app, socketCallback) { return; } } catch (e) { - pushLogs(root, 'join-room', e); + pushLogs(config, 'join-room', e); } try { @@ -961,7 +936,7 @@ module.exports = exports = function(root, app, socketCallback) { return; } } catch (e) { - pushLogs(root, 'join-room.password', e); + pushLogs(config, 'join-room.password', e); } try { @@ -970,7 +945,7 @@ module.exports = exports = function(root, app, socketCallback) { return; } } catch (e) { - pushLogs(root, 'join-room.ROOM_FULL', e); + pushLogs(config, 'join-room.ROOM_FULL', e); } // append this user into participants list @@ -987,7 +962,7 @@ module.exports = exports = function(root, app, socketCallback) { extra: arg.extra }; } catch (e) { - pushLogs(root, 'join-room', e); + pushLogs(config, 'join-room', e); } sendToAdmin(); @@ -995,7 +970,7 @@ module.exports = exports = function(root, app, socketCallback) { try { callback(true); } catch (e) { - pushLogs(root, 'join-room', e); + pushLogs(config, 'join-room', e); } }); @@ -1005,7 +980,7 @@ module.exports = exports = function(root, app, socketCallback) { delete socket.namespace.sockets[this.id]; } } catch (e) { - pushLogs(root, 'disconnect', e); + pushLogs(config, 'disconnect', e); } try { @@ -1022,7 +997,7 @@ module.exports = exports = function(root, app, socketCallback) { } } } catch (e) { - pushLogs(root, 'disconnect', e); + pushLogs(config, 'disconnect', e); } closeOrShiftRoom(); @@ -1041,9 +1016,5 @@ module.exports = exports = function(root, app, socketCallback) { sendToAdmin(); }); - - if (socketCallback) { - socketCallback(socket); - } } }; diff --git a/node_scripts/after-http-listen.js b/node_scripts/after-http-listen.js new file mode 100644 index 0000000..302ba37 --- /dev/null +++ b/node_scripts/after-http-listen.js @@ -0,0 +1,48 @@ +// Muaz Khan - www.MuazKhan.com +// MIT License - www.WebRTC-Experiment.com/licence +// Documentation - github.com/muaz-khan/RTCMultiConnection + +// pushLogs is used to write error logs into logs.json +const pushLogs = require('./pushLogs.js'); +const BASH_COLORS_HELPER = require('./BASH_COLORS_HELPER.js'); + +module.exports = exports = function(httpServer, config) { + try { + var addr = httpServer.address(); + + if (addr.address === '0.0.0.0') { + addr.address = 'localhost'; + } + + var domainURL = (config.isUseHTTPs ? 'https' : 'http') + '://' + addr.address + ':' + addr.port + '/'; + + console.log('\n'); + + console.log('Socket.io is listening at:'); + console.log(BASH_COLORS_HELPER.getGreenFG(), '\t' + domainURL); + + if (!config.isUseHTTPs) { + console.log('You can use --ssl to enable HTTPs:'); + console.log(BASH_COLORS_HELPER.getYellowFG(), '\t' + 'node server --ssl'); + } + + console.log('Your web-browser (HTML file) MUST set this line:'); + console.log(BASH_COLORS_HELPER.getGreenFG(), '\tconnection.socketURL = "' + domainURL + '";'); + + if (addr.address != 'localhost' && !config.isUseHTTPs) { + console.log(BASH_COLORS_HELPER.getRedBG(), 'Warning:'); + console.log(BASH_COLORS_HELPER.getRedBG(), 'Please run on HTTPs to make sure audio,video and screen demos can work on Google Chrome as well.'); + } + + if (config.enableAdmin === true) { + console.log('Admin page is enabled and running on: ' + domainURL + 'admin/'); + console.log('\tAdmin page username: ' + config.adminUserName); + console.log('\tAdmin page password: ' + config.adminPassword); + } + + console.log('For more help: ', BASH_COLORS_HELPER.getYellowFG('node server.js --help')); + console.log('\n'); + } catch (e) { + pushLogs(config, 'app.listen.callback', e); + } +}; diff --git a/node_scripts/before-http-listen.js b/node_scripts/before-http-listen.js new file mode 100644 index 0000000..3fc87fd --- /dev/null +++ b/node_scripts/before-http-listen.js @@ -0,0 +1,91 @@ +// Muaz Khan - www.MuazKhan.com +// MIT License - www.WebRTC-Experiment.com/licence +// Documentation - github.com/muaz-khan/RTCMultiConnection + +// pushLogs is used to write error logs into logs.json +const pushLogs = require('./pushLogs.js'); +const BASH_COLORS_HELPER = require('./BASH_COLORS_HELPER.js'); + +module.exports = exports = function(httpServer, config) { + httpServer.on('error', function(e) { + pushLogs(config, 'app.onerror', e); + + if (e.code != 'EADDRINUSE') return; + + try { + function cmd_exec(cmd, args, cb_stdout, cb_end) { + try { + var spawn = require('child_process').spawn; + var child = spawn(cmd, args); + var me = this; + me.exit = 0; + me.stdout = ""; + child.stdout.on('data', function(data) { + try { + cb_stdout(me, data); + } catch (e) { + pushLogs(config, 'stdout.data', e); + } + }); + child.stdout.on('end', function() { + try { + cb_end(me); + } catch (e) { + pushLogs(config, 'stdout.end', e); + } + }); + } catch (e) { + pushLogs(config, 'cmd_exec', e); + } + } + + function log_console() { + try { + console.log(foo.stdout); + + var pidToBeKilled = foo.stdout.split('\nnode ')[1].split(' ')[0]; + console.log('------------------------------'); + console.log('Please execute below command:'); + console.log('\x1b[31m%s\x1b[0m ', 'kill ' + pidToBeKilled); + console.log('Then try to run "server.js" again.'); + console.log('------------------------------'); + + } catch (e) { + pushLogs(config, 'log_console', e); + } + } + + if (e.address === '0.0.0.0') { + e.address = 'localhost'; + } + + var socketURL = (config.isUseHTTPs ? 'https' : 'http') + '://' + e.address + ':' + e.port + '/'; + + console.log('------------------------------'); + console.log('\x1b[31m%s\x1b[0m ', 'Unable to listen on port: ' + e.port); + console.log('\x1b[31m%s\x1b[0m ', socketURL + ' is already in use. Please kill below processes using "kill PID".'); + console.log('------------------------------'); + + foo = new cmd_exec('lsof', ['-n', '-i4TCP:9001'], + function(me, data) { + try { + me.stdout += data.toString(); + } catch (e) { + pushLogs(config, 'lsof', e); + } + }, + function(me) { + try { + me.exit = 1; + } catch (e) { + pushLogs(config, 'lsof.exit', e); + } + } + ); + + setTimeout(log_console, 250); + } catch (e) { + pushLogs(config, 'app.onerror.EADDRINUSE', e); + } + }); +}; diff --git a/node_scripts/get-values-from-config-json.js b/node_scripts/get-values-from-config-json.js index 5f41930..398e2b8 100644 --- a/node_scripts/get-values-from-config-json.js +++ b/node_scripts/get-values-from-config-json.js @@ -2,7 +2,7 @@ // MIT License - www.WebRTC-Experiment.com/licence // Documentation - github.com/muaz-khan/RTCMultiConnection -function getValues(root) { +function getValues(param) { var path = require('path'); var fs = require('fs'); var getJsonFile = require('./getJsonFile.js'); @@ -26,12 +26,12 @@ function getValues(root) { }; - if (!fs.existsSync(root.config)) { - console.log('File does not exist', root.config); + if (!fs.existsSync(param.config)) { + console.log('File does not exist', param.config); return result; } - var config = getJsonFile(root.config); + var config = getJsonFile(param.config); ['sslKey', 'sslCert', 'sslCabundle'].forEach(function(key) { if (!config[key] || config[key].toString().length == 0) { diff --git a/node_scripts/index.js b/node_scripts/index.js index 0fb2129..15778cf 100644 --- a/node_scripts/index.js +++ b/node_scripts/index.js @@ -2,288 +2,14 @@ // MIT License - www.WebRTC-Experiment.com/licence // Documentation - github.com/muaz-khan/RTCMultiConnection -module.exports = exports = function(root, callback) { - var fs = require('fs'); - var path = require('path'); - var url = require('url'); - - root = root || {}; - root.config = root.config || 'config.json'; - root.logs = root.logs || 'logs.json'; - - var resolveURL = require('./resolveURL.js'); - var BASH_COLORS_HELPER = require('./BASH_COLORS_HELPER.js'); - - var getValuesFromConfigJson = require('./get-values-from-config-json.js'); - var config = getValuesFromConfigJson(root); - - var getBashParameters = require('./get-bash-parameters.js'); - - config = getBashParameters(config, BASH_COLORS_HELPER); - root.enableLogs = config.enableLogs; // used by "pushLogs" - - var getJsonFile = require('./getJsonFile.js'); - - // pushLogs is used to write error logs into logs.json - var pushLogs = require('./pushLogs.js'); - var server = require(config.isUseHTTPs ? 'https' : 'http'); - - function serverHandler(request, response) { - try { - // to make sure we always get valid info from json file - // even if nested codes are overriding it - config = getValuesFromConfigJson(root); - config = getBashParameters(config, BASH_COLORS_HELPER); - - app.config = config; - } catch (e) { - pushLogs('serverHandler', e); - } - - if (typeof callback === 'function') { - callback(request, response, config, root, BASH_COLORS_HELPER, pushLogs, resolveURL, getJsonFile); - } else { - response.writeHead(200, { - 'Content-Type': 'text/plain' - }); - response.write('RTCMultiConnection Socket.io Server.\n\n' + 'https://github.com/muaz-khan/RTCMultiConnection-Server\n\n' + 'npm install RTCMultiConnection-Server'); - response.end(); - } - } - - var app; - - try { - if (config.isUseHTTPs) { - // See how to use a valid certificate: - // https://github.com/muaz-khan/WebRTC-Experiment/issues/62 - var options = { - key: null, - cert: null, - ca: null - }; - - var pfx = false; - - if (!fs.existsSync(config.sslKey)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslKey:\t ' + config.sslKey + ' does not exist.'); - } else { - pfx = config.sslKey.indexOf('.pfx') !== -1; - options.key = fs.readFileSync(config.sslKey); - } - - if (!fs.existsSync(config.sslCert)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCert:\t ' + config.sslCert + ' does not exist.'); - } else { - options.cert = fs.readFileSync(config.sslCert); - } - - if (config.sslCabundle) { - if (!fs.existsSync(config.sslCabundle)) { - console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCabundle:\t ' + config.sslCabundle + ' does not exist.'); - } - - options.ca = fs.readFileSync(config.sslCabundle); - } - - if (pfx === true) { - options = { - pfx: sslKey - }; - } - - app = server.createServer(options, serverHandler); - } else { - app = server.createServer(serverHandler); - } - } catch (e) { - pushLogs(root, 'createServer', e); - } - - function runServer() { - try { - app.on('error', function(e) { - pushLogs(root, 'app.onerror', e); - - if (e.code != 'EADDRINUSE') return; - - try { - function cmd_exec(cmd, args, cb_stdout, cb_end) { - try { - var spawn = require('child_process').spawn; - var child = spawn(cmd, args); - var me = this; - me.exit = 0; - me.stdout = ""; - child.stdout.on('data', function(data) { - try { - cb_stdout(me, data); - } catch (e) { - pushLogs(root, 'stdout.data', e); - } - }); - child.stdout.on('end', function() { - try { - cb_end(me); - } catch (e) { - pushLogs(root, 'stdout.end', e); - } - }); - } catch (e) { - pushLogs(root, 'cmd_exec', e); - } - } - - function log_console() { - try { - console.log(foo.stdout); - - var pidToBeKilled = foo.stdout.split('\nnode ')[1].split(' ')[0]; - console.log('------------------------------'); - console.log('Please execute below command:'); - console.log('\x1b[31m%s\x1b[0m ', 'kill ' + pidToBeKilled); - console.log('Then try to run "server.js" again.'); - console.log('------------------------------'); - - } catch (e) { - pushLogs(root, 'log_console', e); - } - } - - if (e.address === '0.0.0.0') { - e.address = 'localhost'; - } - - var socketURL = (config.isUseHTTPs ? 'https' : 'http') + '://' + e.address + ':' + e.port + '/'; - - console.log('------------------------------'); - console.log('\x1b[31m%s\x1b[0m ', 'Unable to listen on port: ' + e.port); - console.log('\x1b[31m%s\x1b[0m ', socketURL + ' is already in use. Please kill below processes using "kill PID".'); - console.log('------------------------------'); - - foo = new cmd_exec('lsof', ['-n', '-i4TCP:9001'], - function(me, data) { - try { - me.stdout += data.toString(); - } catch (e) { - pushLogs(root, 'lsof', e); - } - }, - function(me) { - try { - me.exit = 1; - } catch (e) { - pushLogs(root, 'lsof.exit', e); - } - } - ); - - setTimeout(log_console, 250); - } catch (e) { - pushLogs(root, 'app.onerror.EADDRINUSE', e); - } - }); - - app = app.listen(config.port, process.env.IP || '0.0.0.0', function(error) { - try { - var addr = app.address(); - - if (addr.address === '0.0.0.0') { - addr.address = 'localhost'; - } - - var domainURL = (config.isUseHTTPs ? 'https' : 'http') + '://' + addr.address + ':' + addr.port + '/'; - - console.log('\n'); - - console.log('Socket.io is listening at:'); - console.log(BASH_COLORS_HELPER.getGreenFG(), '\t' + domainURL); - - if (!config.isUseHTTPs) { - console.log('You can use --ssl to enable HTTPs:'); - console.log(BASH_COLORS_HELPER.getYellowFG(), '\t' + 'node server --ssl'); - } - - console.log('Your web-browser (HTML file) MUST set this line:'); - console.log(BASH_COLORS_HELPER.getGreenFG(), '\tconnection.socketURL = "' + domainURL + '";'); - - if (addr.address != 'localhost' && !config.isUseHTTPs) { - console.log(BASH_COLORS_HELPER.getRedBG(), 'Warning:'); - console.log(BASH_COLORS_HELPER.getRedBG(), 'Please run on HTTPs to make sure audio,video and screen demos can work on Google Chrome as well.'); - } - - if (config.enableAdmin === true) { - console.log('Admin page is enabled and running on: ' + domainURL + 'admin/'); - console.log('\tAdmin page username: ' + config.adminUserName); - console.log('\tAdmin page password: ' + config.adminPassword); - } - - console.log('For more help: ', BASH_COLORS_HELPER.getYellowFG('node server.js --help')); - console.log('\n'); - } catch (e) { - pushLogs(root, 'app.listen.callback', e); - } - }); - } catch (e) { - pushLogs(root, 'app.listen', e); - } - - try { - require('./Signaling-Server.js')(root, app, function(socket) { - try { - var params = socket.handshake.query; - - // "socket" object is totally in your own hands! - // do whatever you want! - - // in your HTML page, you can access socket as following: - // connection.socketCustomEvent = 'custom-message'; - // var socket = connection.getSocket(); - // socket.emit(connection.socketCustomEvent, { test: true }); - - if (!params.socketCustomEvent) { - params.socketCustomEvent = 'custom-message'; - } - - socket.on(params.socketCustomEvent, function(message) { - try { - socket.broadcast.emit(params.socketCustomEvent, message); - } catch (e) { - pushLogs(root, 'socket.broadcast.socketCustomEvent'); - } - }); - } catch (e) { - pushLogs(root, 'Signaling-Server.callback', e); - } - }); - } catch (e) { - pushLogs(root, 'require.Signaling-Server', e); - } - } - - if (config.autoRebootServerOnFailure) { - try { - // auto restart app on failure - var cluster = require('cluster'); - if (cluster.isMaster) { - cluster.fork(); - - cluster.on('exit', function(worker, code, signal) { - try { - cluster.fork(); - } catch (e) { - pushLogs(root, 'cluster.exit.fork', e); - } - }); - } - - if (cluster.isWorker) { - runServer(); - } - } catch (e) { - pushLogs(root, 'cluster.require.fork', e); - } - } else { - runServer(); - } +module.exports = { + resolveURL: require('./resolveURL.js'), + BASH_COLORS_HELPER: require('./BASH_COLORS_HELPER.js'), + getValuesFromConfigJson: require('./get-values-from-config-json.js'), + getBashParameters: require('./get-bash-parameters.js'), + getJsonFile: require('./getJsonFile.js'), + pushLogs: require('./pushLogs.js'), + beforeHttpListen: require('./before-http-listen.js'), + afterHttpListen: require('./after-http-listen.js'), + addSocket: require('./Signaling-Server.js') }; diff --git a/node_scripts/pushLogs.js b/node_scripts/pushLogs.js index e212ed1..3bdefb6 100644 --- a/node_scripts/pushLogs.js +++ b/node_scripts/pushLogs.js @@ -5,9 +5,9 @@ var fs = require('fs'); var getJsonFile = require('./getJsonFile.js'); -function pushLogs(root, name, error, clearLogsCallback) { +function pushLogs(config, name, error, clearLogsCallback) { // return console.log(error.message, error.stack); - if (!root.enableLogs) { + if (!config.enableLogs) { try { console.log(name, error.message, error.stack); } @@ -27,7 +27,7 @@ function pushLogs(root, name, error, clearLogsCallback) { utcDateString += (Math.random() * 100).toString(); utcDateString = utcDateString.replace(/ |-|,|:|\./g, ''); - var logs = getJsonFile(root.logs); + var logs = getJsonFile(config.logs); try { if (!!clearLogsCallback && typeof clearLogsCallback === 'function') { @@ -41,7 +41,7 @@ function pushLogs(root, name, error, clearLogsCallback) { }; } - fs.writeFileSync(root.logs, JSON.stringify(logs)); + fs.writeFileSync(config.logs, JSON.stringify(logs)); if (!!clearLogsCallback && typeof clearLogsCallback === 'function') { clearLogsCallback(true); diff --git a/package.json b/package.json index 5b97685..fb25396 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "rtcmulticonnection-server", "preferGlobal": false, - "version": "1.3.0", + "version": "1.3.1", "author": { "name": "Muaz Khan", "email": "muazkh@gmail.com", diff --git a/server.js b/server.js index 61f82e0..2739d23 100644 --- a/server.js +++ b/server.js @@ -1,8 +1,119 @@ -require('./node_scripts/index.js')(); +// http://127.0.0.1:9001 +// http://localhost:9001 -/* -require('./node_scripts/index.js')({ - config: __dirname + resolveURL('/config.json'), - logs: __dirname + resolveURL('/logs.json') +const fs = require('fs'); +const path = require('path'); +const url = require('url'); +var httpServer = require('http'); + +const ioServer = require('socket.io'); +const RTCMultiConnectionServer = require('./node_scripts/index.js'); + +var PORT = 9001; +var isUseHTTPs = false; + +const jsonPath = { + config: 'config.json', + logs: 'logs.json' +}; + +const BASH_COLORS_HELPER = RTCMultiConnectionServer.BASH_COLORS_HELPER; +const getValuesFromConfigJson = RTCMultiConnectionServer.getValuesFromConfigJson; +const getBashParameters = RTCMultiConnectionServer.getBashParameters; + +var config = getValuesFromConfigJson(jsonPath); +config = getBashParameters(config, BASH_COLORS_HELPER); + +// if user didn't modifed "PORT" object +// then read value from "config.json" +if(PORT === 9001) { + PORT = config.port; +} +if(isUseHTTPs === false) { + isUseHTTPs = config.isUseHTTPs; +} + +function serverHandler(request, response) { + // to make sure we always get valid info from json file + // even if external codes are overriding it + config = getValuesFromConfigJson(jsonPath); + config = getBashParameters(config, BASH_COLORS_HELPER); + + response.writeHead(200, { + 'Content-Type': 'text/plain' + }); + response.write('RTCMultiConnection Socket.io Server.\n\n' + 'https://github.com/muaz-khan/RTCMultiConnection-Server\n\n' + 'npm install RTCMultiConnection-Server'); + response.end(); +} + +var httpApp; + +if (isUseHTTPs) { + httpServer = require('https'); + + // See how to use a valid certificate: + // https://github.com/muaz-khan/WebRTC-Experiment/issues/62 + var options = { + key: null, + cert: null, + ca: null + }; + + var pfx = false; + + if (!fs.existsSync(config.sslKey)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslKey:\t ' + config.sslKey + ' does not exist.'); + } else { + pfx = config.sslKey.indexOf('.pfx') !== -1; + options.key = fs.readFileSync(config.sslKey); + } + + if (!fs.existsSync(config.sslCert)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCert:\t ' + config.sslCert + ' does not exist.'); + } else { + options.cert = fs.readFileSync(config.sslCert); + } + + if (config.sslCabundle) { + if (!fs.existsSync(config.sslCabundle)) { + console.log(BASH_COLORS_HELPER.getRedFG(), 'sslCabundle:\t ' + config.sslCabundle + ' does not exist.'); + } + + options.ca = fs.readFileSync(config.sslCabundle); + } + + if (pfx === true) { + options = { + pfx: sslKey + }; + } + + httpApp = httpServer.createServer(options, serverHandler); +} else { + httpApp = httpServer.createServer(serverHandler); +} + +RTCMultiConnectionServer.beforeHttpListen(httpApp, config); +httpApp = httpApp.listen(process.env.PORT || PORT, process.env.IP || "0.0.0.0", function() { + RTCMultiConnectionServer.afterHttpListen(httpApp, config); +}); + +// -------------------------- +// socket.io codes goes below + +ioServer(httpApp).on('connection', function(socket) { + RTCMultiConnectionServer.addSocket(socket, config); + + // ---------------------- + // below code is optional + + const params = socket.handshake.query; + + if (!params.socketCustomEvent) { + params.socketCustomEvent = 'custom-message'; + } + + socket.on(params.socketCustomEvent, function(message) { + socket.broadcast.emit(params.socketCustomEvent, message); + }); }); -*/