diff --git a/app/electron/main.js b/app/electron/main.js index 23a691a32..7d1e179f2 100644 --- a/app/electron/main.js +++ b/app/electron/main.js @@ -34,7 +34,6 @@ const isDevEnv = process.env.NODE_ENV === 'development' const appVer = app.getVersion() const confDir = path.join(app.getPath('home'), '.config', 'siyuan') const windowStatePath = path.join(confDir, 'windowState.json') -const portJSONPath = path.join(confDir, 'port.json') let tray // 托盘必须使用全局变量,以防止被垃圾回收 https://www.electronjs.org/docs/faq#my-apps-windowtray-disappeared-after-a-few-minutes let mainWindow // 从托盘处激活报错 https://github.com/siyuan-note/siyuan/issues/769 let firstOpenWindow, bootWindow @@ -42,7 +41,6 @@ let closeButtonBehavior = 0 let siyuanOpenURL let firstOpen = false let resetWindowStateOnRestart = false -let kernelPort = "6806" const localhost = "127.0.0.1" require('@electron/remote/main').initialize() @@ -51,10 +49,6 @@ if (!app.requestSingleInstanceLock()) { return } -const getServer = () => { - return "http://" + localhost + ":" + kernelPort -} - const showErrorWindow = (title, content) => { let errorHTMLPath = path.join(appDir, 'app', 'electron', 'error.html') if (isDevEnv) { @@ -554,6 +548,46 @@ const boot = () => { } } +let kernelPort = 6806 +let tryGetPortCount = 0 +const net = require("net"); +const getAvailablePort = (port = kernelPort) => { + // https://gist.github.com/mikeal/1840641 + + const server = net.createServer() + return new Promise((resolve, reject) => server + .on('error', error => { + writeLog(error) + if (2048 < ++tryGetPortCount) { + writeLog('failed to get available port [tryCount=' + tryGetPortCount + ', port=' + port + ']') + reject(error) + return + } + server.listen(++port) + }) + .on('listening', () => { + writeLog('found an available port [' + port + ']') + server.close(() => resolve(port)) + }) + .listen(port, '127.0.0.1')) +} + +const getKernelPort = async () => { + if (isDevEnv) { + writeLog("got kernel port [" + kernelPort + "]") + return kernelPort + } + + // 改进桌面端拉起内核 https://github.com/siyuan-note/siyuan/issues/6894 + kernelPort = await getAvailablePort() + writeLog("got kernel available port [" + kernelPort + "]") + return kernelPort +} + +const getServer = () => { + return "http://" + localhost + ":" + kernelPort +} + const initKernel = (initData) => { return new Promise(async (resolve) => { bootWindow = new BrowserWindow({ @@ -577,7 +611,8 @@ const initKernel = (initData) => { return } - const cmds = ['--wd', appDir] + const availablePort = await getKernelPort() + const cmds = ['--port', availablePort, '--wd', appDir] if (isDevEnv) { cmds.push('--mode', 'dev') } @@ -639,44 +674,6 @@ const initKernel = (initData) => { }) } - const getKernelPort = async () => { - if (isDevEnv) { - return kernelPort - } - - await sleep(200) - let gotPort = false - let count = 0 - while (!gotPort) { - try { - const portJSON = JSON.parse(fs.readFileSync(portJSONPath, 'utf8')) - const ret = portJSON[kernelProcessPid] - if (ret) { - gotPort = true - return ret - } - await sleep(100) - } catch (e) { - await sleep(100) - } finally { - count++ - if (64 < count) { - writeLog('get kernel port failed [pid=' + kernelProcessPid + ']') - return - } - } - } - } - - kernelPort = await getKernelPort() - if (!kernelPort) { - showErrorWindow('⚠️ 获取内核服务端口失败 Failed to get kernel serve port', - '