From 70db878c2e9125f1efdbf77cbd97c8fc948200b7 Mon Sep 17 00:00:00 2001 From: zhangyan Date: Wed, 20 Nov 2024 17:04:37 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=94=AF=E6=8C=81=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=90=8C=E6=97=B6=E5=8D=87=E7=BA=A7=E6=97=B6?= =?UTF-8?q?=E5=8F=AF=E6=84=9F=E7=9F=A5=E5=8D=87=E7=BA=A7=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zhangyan --- app.js | 18 ++++++---- update/update.js | 86 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 34 deletions(-) diff --git a/app.js b/app.js index aad4c71..5494b4f 100644 --- a/app.js +++ b/app.js @@ -40,17 +40,21 @@ wss.on('connection', function connection(ws) { }; pluginSystem.execute(decoderMessage.type, 'process', decoderMessage.session_id, decoderMessage.cmd, decoderMessage.data); }; - // type为升级 - if (decoderMessage.type === TypeManage.TypeConfig.UPDATE_TYPE) { - const UPDATE = require('./update/update.js'); - UPDATE.process(ws, decoderMessage); - return; - } // 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) { + 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); @@ -101,8 +105,10 @@ function sendMsgToClient(type, sessionId, cmd, data) { // 各个业务模块在这里初始化,注册函数 function initPlugins() { const AI = require('./ai/ai.js'); + const UPDATE = require('./update/update.js'); // 加载AI_Plugins插件的init AI.init(); + UPDATE.init(); } // 函数注册和调用 diff --git a/update/update.js b/update/update.js index b567931..f8b5750 100644 --- a/update/update.js +++ b/update/update.js @@ -18,26 +18,35 @@ const unzipper = require('unzipper'); const { exit } = require('process'); const TypeManage = require('../typeManage.js'); const Version = require('../version.js'); -const { Utils } = require('../Util.js'); const updateZipPath = path.join(__dirname, 'update.zip'); const GET_CMD = 1; const UPDATE_CMD = 3; -let isUpdate = true; +const UPDATE_SUCCESS_CMD = 2; // 升级成功 +const UPDATE_FAIL_CMD = 4; // 升级失败 +let isUpdate = false; +let sessionIdMap = new Map(); - -function process(ws, message) { +function init() { + const apps = require('../app'); + apps.pluginSystem.registerPlugin(TypeManage.TypeConfig.UPDATE_TYPE, process, singleDelete); + clear(); +} +function process(session_id, cmd, message) { // 获取扩展程序版本号 - if (message.cmd === GET_CMD) { + if (cmd === GET_CMD) { // 返回扩展程序当前版本 - sendMsg(ws) + sendMsg(session_id, GET_CMD, Version.version.version) // 升级版本 - } else if (message.cmd === UPDATE_CMD) { + } else if (cmd === UPDATE_CMD) { // 设置标记位 - if (isUpdate) { - isUpdate = false; - update(message.data)// 升级完退出服务 + if (!isUpdate) { + isUpdate = true; + update(session_id, message)// 升级完退出服务 + } + // 缓存多个session同时升级的场景 + if (!sessionIdMap.has(session_id)) { + sessionIdMap.set(session_id, session_id); } - } } @@ -45,56 +54,77 @@ function process(ws, message) { * 解压新包 * 替换、新增 */ -function update(data) { +function update(session_id, data) { // 将文件写入update/update.zip fs.writeFile(updateZipPath, data, (err) => { if (err) { console.error('File write failed:', err); + isUpdate = false; + publishStatus(UPDATE_FAIL_CMD); + sendMsg(session_id, UPDATE_FAIL_CMD, ''); return; } // 获取项目根目录 - let rootDir = findProjectRoot(path.dirname(__dirname)); + let rootDir = findProjectRoot(session_id, path.dirname(__dirname)); fs.createReadStream(updateZipPath) .pipe(unzipper.Extract({ path: rootDir})) .promise() .then(() => { // 删除临时文件 fs.unlinkSync(updateZipPath); + publishStatus(UPDATE_SUCCESS_CMD); + sendMsg(session_id, UPDATE_SUCCESS_CMD, ''); // 正常退出进程 exit(0); }) .catch((err) => { - console.error(err) + isUpdate = false; + publishStatus(UPDATE_FAIL_CMD); + sendMsg(session_id, UPDATE_FAIL_CMD, '') + console.error(err); }) }) } // 定位根目录 -function findProjectRoot(startDir) { +function findProjectRoot(session_id, startDir) { let currentDir = startDir; while (!fs.existsSync(path.join(currentDir, 'package.json'))) { let parentDir = path.dirname(currentDir); if (parentDir === currentDir) { - console.error('err: 已经达到根目录但未找到package.json'); + isUpdate = false; + publishStatus(UPDATE_FAIL_CMD); + sendMsg(session_id, UPDATE_FAIL_CMD, '') + console.error('err: Reached root directory but package. json not found'); } currentDir = parentDir; } return currentDir; } -// 将信息send至服务器 -function sendMsg(ws) { - let version = new TextEncoder().encode(Version.version.version); - let versionMsg = { - type: TypeManage.TypeConfig.UPDATE_TYPE, - cmd: GET_CMD, - session_id: '', - session: '', - data: version, - data_lenght: version.byteLength +// 同时打开多个页面均可感知升级状态 +function publishStatus(cmd) { + for (const session_id of sessionIdMap.values()) { + sendMsg(session_id, cmd, ''); } - ws.send(Utils.encode(versionMsg)) + clear(); +} + +// 删除sessionId对应的键值对 +function singleDelete(session_id) { + sessionIdMap.delete(session_id); +} + +// 每次当扩展程序初始化时,清空Map对象 +function clear() { + sessionIdMap.clear(); +} + +// 将信息send至服务器 +function sendMsg(session_id, cmd, data) { + const app = require('../app'); + app.sendMsgToClient(TypeManage.TypeConfig.UPDATE_TYPE, session_id, cmd, new TextEncoder().encode(data)); } module.exports = { - process + init } \ No newline at end of file -- Gitee