diff --git a/app/electron/main.js b/app/electron/main.js index 60d19818d..4d95f61a2 100644 --- a/app/electron/main.js +++ b/app/electron/main.js @@ -34,6 +34,7 @@ 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 @@ -41,6 +42,7 @@ let closeButtonBehavior = 0 let siyuanOpenURL let firstOpen = false let resetWindowStateOnRestart = false +let kernelPort = "6806" require('@electron/remote/main').initialize() if (!app.requestSingleInstanceLock()) { @@ -92,6 +94,7 @@ try { } const writeLog = (out) => { + console.log(out) const logFile = path.join(confDir, 'app.log') let log = '' const maxLogLines = 1024 @@ -263,7 +266,7 @@ const boot = () => { }) // 加载主界面 - mainWindow.loadURL('http://127.0.0.1:6806/stage/build/app/index.html?v=' + + mainWindow.loadURL('http://127.0.0.1:' + kernelPort + '/stage/build/app/index.html?v=' + new Date().getTime()) // 菜单 @@ -327,7 +330,7 @@ const boot = () => { Menu.setApplicationMenu(menu) // 当前页面链接使用浏览器打开 mainWindow.webContents.on('will-navigate', (event, url) => { - if (url.startsWith('http://127.0.0.1:6806')) { + if (url.startsWith('http://127.0.0.1:' + kernelPort)) { return } @@ -337,7 +340,7 @@ const boot = () => { // IFrame 块不跟随重定向 https://github.com/siyuan-note/siyuan/issues/6327 mainWindow.webContents.on('will-redirect', (event, url, isInPlace, isMainFrame) => { - if (url.startsWith('http://127.0.0.1:6806')) { + if (url.startsWith('http://127.0.0.1:' + kernelPort)) { return } @@ -408,7 +411,7 @@ const boot = () => { theme: nativeTheme.shouldUseDarkColors ? 'dark' : 'light', init: true, }) - await fetch('http://127.0.0.1:6806/api/system/uiproc?pid=' + process.pid, + await fetch('http://127.0.0.1:' + kernelPort + '/api/system/uiproc?pid=' + process.pid, {method: 'POST'}) }) ipcMain.on('siyuan-hotkey', (event, hotkey) => { @@ -551,6 +554,7 @@ const initKernel = (initData) => { stdio: 'ignore', }, ) + writeLog('booted kernel process [pid=' + kernelProcess.pid + ']') kernelProcess.on('close', (code) => { if (0 !== code) { @@ -561,11 +565,11 @@ const initKernel = (initData) => { `
数据库文件正在被其他程序锁定。如果你使用了第三方同步盘,请在思源运行期间关闭同步。
The database file is being locked by another program. If you use a third-party sync disk, please turn off sync while SiYuan is running.
`) break case 21: - showErrorWindow('⚠️ 6806 端口不可用 The port 6806 is unavailable', - '
思源需要监听 6806 端口,请确保该端口可用且不是其他程序的保留端口。可尝试使用管理员运行命令:' + - '
net stop winnat\nnetsh interface ipv4 add excludedportrange protocol=tcp startport=6806 numberofports=1\nnet start winnat
' + - '
SiYuan needs to listen to port 6806, please make sure this port is available, and not a reserved port by other software. Try running the command as an administrator: ' + - '
net stop winnat\nnetsh interface ipv4 add excludedportrange protocol=tcp startport=6806 numberofports=1\nnet start winnat
') + showErrorWindow('⚠️ ' + kernelPort + ' 端口不可用 The port ' + kernelPort + ' is unavailable', + '
思源需要监听 ' + kernelPort + ' 端口,请确保该端口可用且不是其他程序的保留端口。可尝试使用管理员运行命令:' + + '
net stop winnat\nnetsh interface ipv4 add excludedportrange protocol=tcp startport=' + kernelPort + ' numberofports=1\nnet start winnat
' + + '
SiYuan needs to listen to port ' + kernelPort + ', please make sure this port is available, and not a reserved port by other software. Try running the command as an administrator: ' + + '
net stop winnat\nnetsh interface ipv4 add excludedportrange protocol=tcp startport=' + kernelPort + ' numberofports=1\nnet start winnat
') break case 22: showErrorWindow( @@ -593,28 +597,54 @@ const initKernel = (initData) => { } }) - writeLog('booted kernel process') - const sleep = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)) } + const getKernelPort = async () => { + await sleep(200) + let gotPort = false + let count = 0 + while (!gotPort) { + try { + const portJSON = JSON.parse(fs.readFileSync(portJSONPath, 'utf8')) + const ret = portJSON[kernelProcess.pid.toString()] + 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=' + kernelProcess.pid + ']') + bootWindow.destroy() + resolve(false) + } + } + } + } + + kernelPort = await getKernelPort() + writeLog("got kernel port [" + kernelPort + "]") + let gotVersion = false let apiData let count = 0 writeLog('checking kernel version') while (!gotVersion) { try { - const apiResult = await fetch( - 'http://127.0.0.1:6806/api/system/version') + const apiResult = await fetch('http://127.0.0.1:' + kernelPort + '/api/system/version') apiData = await apiResult.json() gotVersion = true bootWindow.setResizable(false) - bootWindow.loadURL('http://127.0.0.1:6806/appearance/boot/index.html') + bootWindow.loadURL('http://127.0.0.1:' + kernelPort + '/appearance/boot/index.html') bootWindow.show() } catch (e) { writeLog('get kernel version failed: ' + e.message) - await sleep(100) + await sleep(200) } finally { count++ if (64 < count) { @@ -630,15 +660,14 @@ const initKernel = (initData) => { if (!isDevEnv && apiData.data !== appVer) { writeLog( `kernel [${apiData.data}] is running, shutdown it now and then start kernel [${appVer}]`) - fetch('http://127.0.0.1:6806/api/system/exit', {method: 'POST'}) + fetch('http://127.0.0.1:' + kernelPort + '/api/system/exit', {method: 'POST'}) bootWindow.destroy() resolve(false) } else { let progressing = false while (!progressing) { try { - const progressResult = await fetch( - 'http://127.0.0.1:6806/api/system/bootProgress') + const progressResult = await fetch('http://127.0.0.1:' + kernelPort + '/api/system/bootProgress') const progressData = await progressResult.json() if (progressData.data.progress >= 100) { resolve(true) @@ -648,7 +677,7 @@ const initKernel = (initData) => { } } catch (e) { writeLog('get boot progress failed: ' + e.message) - fetch('http://127.0.0.1:6806/api/system/exit', {method: 'POST'}) + fetch('http://127.0.0.1:' + kernelPort + '/api/system/exit', {method: 'POST'}) bootWindow.destroy() resolve(false) progressing = true @@ -778,15 +807,15 @@ const {powerMonitor} = require('electron') powerMonitor.on('suspend', () => { writeLog('system suspend') - fetch('http://127.0.0.1:6806/api/sync/performSync', {method: 'POST'}) + fetch('http://127.0.0.1:' + kernelPort + '/api/sync/performSync', {method: 'POST'}) }) powerMonitor.on('resume', () => { writeLog('system resume') - fetch('http://127.0.0.1:6806/api/sync/performSync', {method: 'POST'}) + fetch('http://127.0.0.1:' + kernelPort + '/api/sync/performSync', {method: 'POST'}) }) powerMonitor.on('shutdown', () => { writeLog('system shutdown') - fetch('http://127.0.0.1:6806/api/system/exit', {method: 'POST'}) + fetch('http://127.0.0.1:' + kernelPort + '/api/system/exit', {method: 'POST'}) })