UNPKG

scalra

Version:

node.js framework to prototype and scale rapidly

191 lines (146 loc) 5.57 kB
// // serverserver.js // // a basic socket server // // history: // 2016-01-10 extracted from frontier.js // // module object var l_module = exports.module = {}; // a pool for all message handlers var l_handlers = exports.handlers = {}; var l_checkers = exports.checkers = {}; var l_api = exports.api = {}; var l_name = 'SR.Module.socketserver'; //----------------------------------------- // Handlers (format checkers and event handlers) // //----------------------------------------- //----------------------------------------- // Server Event Handling // //----------------------------------------- // default IP & port var l_ip_port = exports.ip_port = {}; // a SR.Listener object var l_server = undefined; // // external functions // // get server instance exports.get = function () { return l_server; }; SR.Callback.onStart(function () { }); SR.Callback.onStop(function () { // tasks when server stops }); // when a client connects SR.Callback.onConnect(function (conn) { // do some config checking & init }); // when a client disconnects SR.Callback.onDisconnect(function (conn) { // handle disconnect }); // module init l_module.start = function (config, onDone) { // process config & verify correctness here LOG.warn('init socket server...', l_name); // NOTE: base port previously indicate 'socket port', but now will be 'HTTP' port var start_server = function () { LOG.warn('starting [' + SR.Settings.SERVER_INFO.type + '] server at base port: ' + l_ip_port.port, l_name); // NOTE: name will determine which handler set to get/store // create a listener that'll listen to the default socket port for this server // start from here step 1 l_server = new SR.Listener({ port: l_ip_port.port + SR.Settings.PORT_INC_SOCKET, conn_module: config.conn_handler }); // always load system.js (NOTE: before other handlers) SR.Handler.addByFile({name: 'system', file: 'system.js', owner: 'SR'}, config.path); // result may be true or false l_server.init(function (result) { if (result === false) { LOG.error('server init fail, listen port: ' + l_ip_port.port, l_name); // NOTE: this is redundant judgement with frontier's //LOG.warn('treat this server as APP server, loading AppConnector...', l_name); //SR.Module.addStep(SR.Component.AppConnector()); // TODO: try to close down more gracefully, right now this will trigger many // unnecessary shutdown steps (& print too many error messages not useful) //l_dispose(); } else { LOG.warn('server is ready & running...', l_name); // for entry server, we report the entry server HTTP base port // TODO: cleaner approach? if (SR.Settings.SERVER_INFO.type === 'entry') SR.Settings.SERVER_INFO.port = SR.Settings.PORT_ENTRY_ACTUAL; // NOTE: this is redundant judgement with frontier's //else if (SR.Settings.SERVER_INFO.type === 'lobby') { // LOG.warn('treat this server as LOBBY server, loading AppManager...', l_name); // SR.Module.addStep(SR.Component.AppManager()); //} } UTIL.safeCall(onDone, true); }); }; // get main server port // the rules are: // 1. for lobby with assigned port, use the assigned port in project's settings.js // 2. monitor server: port is assigned in SR.Settings.PORT_MONITOR // 3. for all else (app servers or unassigned lobby), port is assigned by monitor server (valid for local host) // determine server port var get_port = function (onDone) { // make sure lobby port is a number if (typeof SR.Settings.Project.lobbyPort === 'string') SR.Settings.Project.lobbyPort = parseInt(SR.Settings.Project.lobbyPort); // for lobby server with assigned port if (SR.Settings.SERVER_INFO.type === 'lobby' && typeof UTIL.userSettings('lobbyPort') === 'number') return UTIL.safeCall(onDone, UTIL.userSettings('lobbyPort')); // assign specific port for monitor if (SR.Settings.SERVER_INFO.type === 'monitor') return UTIL.safeCall(onDone, SR.Settings.PORT_MONITOR); // for app servers or for unassigned lobby server, we need to get an available port from monitor server // NOTE: we get up to 10 ports per server (lobby, app, entry) var size = (SR.Settings.SERVER_INFO.type === 'entry' ? 1 : SR.Settings.PORT_RESERVED_SIZE); UTIL.getLocalPort(function (port) { if (port === 0) { LOG.error('cannot get valid port, cannot start server', l_name); UTIL.safeCall(onDone, false); return l_dispose(); } LOG.sys('get monitor assigned port(s): ' + port, l_name); // return only the first one UTIL.safeCall(onDone, (typeof port === 'number' ? port : port[0])); }, size); }; // determine server IP & port then start server // get my own local IP (for future uses) UTIL.getLocalIP(function (local_IP) { LOG.sys('get local IP: ' + local_IP, l_name); l_ip_port.IP = local_IP; get_port(function (port) { l_ip_port.port = port; LOG.warn('server base port: ' + l_ip_port.port, l_name); // update server info with ip & port SR.Settings.SERVER_INFO.IP = l_ip_port.IP; SR.Settings.SERVER_INFO.port = l_ip_port.port; // finally we start the server start_server(); }); }); }; // module shutdown l_module.stop = function (onDone) { // close / release resources used // shutdown server, if exist if (l_server) { l_server.dispose(function () { LOG.warn('socket server stopped...', l_name); l_server = undefined; UTIL.safeCall(onDone, true); }); } };