diff --git a/app.js b/app.js index 46e7db509db8798d5da047fc639e0135aec0b258..431a086e3ac4a3c830f7677e7cfc6651b7310c8e 100644 --- a/app.js +++ b/app.js @@ -12,88 +12,112 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -const WebSocket = require('ws'); +const http = require('http'); const winston = require('winston'); const SessionManage = require('./session.js'); const Utils = require('./Util.js'); const TypeManage = require('./typeManage.js'); -const wss = new WebSocket.Server({ port: `${Utils.AuthMsg.SW_PORT}`, maxPayload: 1024 * 1024 * 500 }); +const { resolve } = require('path'); + // 创建logger const logger = winston.createLogger(require('./winston.config.js')); -// 当有新客户端连接时触发 -wss.on('connection', function connection(ws) { - // WebSocket的一个属性,用于控制 WebSocket 连接如何处理接收到的二进制数据; - ws.binaryType = 'arraybuffer'; - // 接收来自客户端的消息 - ws.on('message', function incoming(message) { - // 判断头部字节数 - if (new Uint8Array(message).byteLength < Utils.AuthMsg.MESSAGE_BYTE) { - return; - }; - let decoderMessage = Utils.Utils.decode(message); - // type为0-7为内置,业务type从8开始 - if (decoderMessage.type > TypeManage.TypeConfig.MAX_BUILTIN_TYPE) { - // 鉴权session和sessionId - let isAuthSuccess = SessionManage.SessionJs.checkSession(decoderMessage.session_id, decoderMessage.session); - if (!isAuthSuccess) { - logger.error(`${decoderMessage.session_id} Authentication failed`); - return; - }; - logger.info(`type:${decoderMessage.type},sessionId:${decoderMessage.session_id},cmd:${decoderMessage.cmd}`); - pluginSystem.execute(decoderMessage.type, 'process', decoderMessage.session_id, decoderMessage.cmd, decoderMessage.data); - }; - // type为会话信息 - if (decoderMessage.type === TypeManage.TypeConfig.LOGIN_TYPE) { - SessionManage.SessionJs.applySession(ws, decoderMessage); - return; - }; - // type为升级 - if (decoderMessage.type === TypeManage.TypeConfig.UPDATE_TYPE) { - // 鉴权session和sessionId - let isAuthSuccess = SessionManage.SessionJs.checkSession(decoderMessage.session_id, decoderMessage.session); - if (!isAuthSuccess) { - logger.error('Authentication failed'); - return; - }; - pluginSystem.execute(decoderMessage.type, 'process', decoderMessage.session_id, decoderMessage.cmd, decoderMessage.data); - return; - } - // type为心跳机制类型 - if (decoderMessage.type === TypeManage.TypeConfig.HEARTBEAT_TYPE) { - ws.send(message); - return; - }; +function isPortInUse(port) { + return new Promise((resolve) => { + const tester = http.createServer(); + tester.listen(port, () => { + tester.close(() => resolve(false));// 端口为被占用 + }); + tester.on('error', (() => resolve(true))); // 端口已被占用 }); +} +(async () => { + const port = Utils.AuthMsg.SW_PORT; + const isUse = await isPortInUse(port); + if (isUse) { + console.error(`端口${port}已被占用,请更换端口或关闭占用该端口的程序`); + process.exit(1); // 退出程序 + } else { + const WebSocket = require('ws'); + console.log(`端口${port}可用,可以启动WebSocket服务`); + const wss = new WebSocket.Server({ port: port, maxPayload: 1024 * 1024 * 500 }); + // 当有新客户端连接时触发 + wss.on('connection', function connection(ws) { + // WebSocket的一个属性,用于控制 WebSocket 连接如何处理接收到的二进制数据; + ws.binaryType = 'arraybuffer'; + // 接收来自客户端的消息 + ws.on('message', function incoming(message) { + // 判断头部字节数 + if (new Uint8Array(message).byteLength < Utils.AuthMsg.MESSAGE_BYTE) { + return; + }; + let decoderMessage = Utils.Utils.decode(message); + // type为0-7为内置,业务type从8开始 + if (decoderMessage.type > TypeManage.TypeConfig.MAX_BUILTIN_TYPE) { + // 鉴权session和sessionId + let isAuthSuccess = SessionManage.SessionJs.checkSession(decoderMessage.session_id, decoderMessage.session); + if (!isAuthSuccess) { + logger.error(`${decoderMessage.session_id} Authentication failed`); + return; + }; + logger.info(`type:${decoderMessage.type},sessionId:${decoderMessage.session_id},cmd:${decoderMessage.cmd}`); + pluginSystem.execute(decoderMessage.type, 'process', decoderMessage.session_id, decoderMessage.cmd, decoderMessage.data); + }; + // type为会话信息 + if (decoderMessage.type === TypeManage.TypeConfig.LOGIN_TYPE) { + SessionManage.SessionJs.applySession(ws, decoderMessage); + return; + }; + // type为升级 + if (decoderMessage.type === TypeManage.TypeConfig.UPDATE_TYPE) { + // 鉴权session和sessionId + let isAuthSuccess = SessionManage.SessionJs.checkSession(decoderMessage.session_id, decoderMessage.session); + if (!isAuthSuccess) { + logger.error('Authentication failed'); + return; + }; + pluginSystem.execute(decoderMessage.type, 'process', decoderMessage.session_id, decoderMessage.cmd, decoderMessage.data); + return; + } + // type为心跳机制类型 + if (decoderMessage.type === TypeManage.TypeConfig.HEARTBEAT_TYPE) { + ws.send(message); + return; + }; + }); - // 当连接关闭时触发--- - ws.on('close', function close() { - // 当关闭服务时,判断是否有sessionId,做保护逻辑,之前发现在客户端连续刷新会出现找不到sessionId,会报错,因此在这里做保护 - if (!ws.userData) { - return; - } - // 判断插件是否有清除缓存的clear方法 - if (Object.keys(pluginSystem.plugins).length > 0) { - // 通知插件清理缓存 - for (const key in pluginSystem.plugins) { - if (pluginSystem.plugins[key]['clear'] && typeof pluginSystem.plugins[key]['clear'] === 'function') { - pluginSystem.execute(key, 'clear', ws.userData.sessionId); + // 当连接关闭时触发--- + ws.on('close', function close() { + // 当关闭服务时,判断是否有sessionId,做保护逻辑,之前发现在客户端连续刷新会出现找不到sessionId,会报错,因此在这里做保护 + if (!ws.userData) { + return; } - } + // 判断插件是否有清除缓存的clear方法 + if (Object.keys(pluginSystem.plugins).length > 0) { + // 通知插件清理缓存 + for (const key in pluginSystem.plugins) { + if (pluginSystem.plugins[key]['clear'] && typeof pluginSystem.plugins[key]['clear'] === 'function') { + pluginSystem.execute(key, 'clear', ws.userData.sessionId); + } + } + + }; + // session管理中清除对应的session + SessionManage.SessionJs.clearSession(ws.userData.sessionId); + }); + + // 当发生错误时触发 + ws.on('error', function error(err) { + if (err.code === 'EADDRINUSE') { + logger.err(`Port ${Utils.AuthMsg.SW_PORT} is occupied`); + } + logger.error(`Connection error:${err}`); + }); + }) + } +})(); - }; - // session管理中清除对应的session - SessionManage.SessionJs.clearSession(ws.userData.sessionId); - }); - // 当发生错误时触发 - ws.on('error', function error(err) { - if(err.code === 'EADDRINUSE') { - logger.err(`Port ${Utils.AuthMsg.SW_PORT} is occupied`); - } - logger.error(`Connection error:${err}`); - }); -}) // 业务侧调,用来往客户端发送消息 // type:Number;sessionId:Number;cmd:Number;data:Uint8Array function sendMsgToClient(type, sessionId, cmd, data) { diff --git a/version.js b/version.js index b67bf7a43daeb1ec9de6d0414fd30586c16b3b3a..332c9cc622f596941b72a58f0ed1f389569d130a 100644 --- a/version.js +++ b/version.js @@ -13,7 +13,7 @@ * limitations under the License. */ class version { - static version = '1.1.1'; //版本号 + static version = '1.1.2'; //版本号 } module.exports = {