github.com/easysoft/zendata@v0.0.0-20240513203326-705bd5a7fd67/client/src/app/core/zd.js (about)

     1  import {app} from 'electron';
     2  import os from 'os';
     3  import path from 'path';
     4  import {execSync, spawn} from 'child_process';
     5  
     6  import {DEBUG, portServer, uuid} from '../utils/consts';
     7  import {IS_WINDOWS_OS} from "../utils/env";
     8  import {logErr, logInfo} from '../utils/log';
     9  
    10  let _zdProcess;
    11  
    12  export async function startZdServer() {
    13      if (process.env.SKIP_SERVER && parseInt(process.env.SKIP_SERVER)) {
    14          logInfo(`>> skip to start zd Server by env "SKIP_SERVER=${process.env.SKIP_SERVER}".`);
    15          return Promise.resolve();
    16      }
    17      if (_zdProcess) {
    18          return Promise.resolve(_zdProcess);
    19      }
    20  
    21      let {SERVER_EXE_PATH: serverExePath} = process.env;
    22      if (!serverExePath && !DEBUG) {
    23          const platform = os.platform(); // 'darwin', 'linux', 'win32'
    24          const exePath = `bin/${platform}/server${platform === 'win32' ? '.exe' : ''}`;
    25          serverExePath = path.join(process.resourcesPath, exePath);
    26      }
    27      if (serverExePath) {
    28          if (!path.isAbsolute(serverExePath)) {
    29              serverExePath = path.resolve(app.getAppPath(), serverExePath);
    30          }
    31          return new Promise((resolve, reject) => {
    32              const cwd = process.env.SERVER_CWD_PATH || path.dirname(serverExePath);
    33              logInfo(`>> starting zd server with command ` +
    34                  `"${serverExePath} -p ${portServer} -uuid ${uuid}" in "${cwd}"...`);
    35  
    36              const cmd = spawn('"'+serverExePath+'"', ['-p', portServer, '-uuid', uuid], {
    37                  cwd,
    38                  shell: true,
    39              });
    40  
    41              _zdProcess = cmd;
    42              logInfo(`>> zd server process = ${_zdProcess.pid}`)
    43  
    44              cmd.on('exit', (code) => {
    45                  logInfo(`>> zd server closed with code ${code}`);
    46                  _zdProcess = null;
    47                  cmd.kill()
    48              });
    49              cmd.stdout.on('data', data => {
    50                  const dataString = String(data);
    51                  const lines = dataString.split('\n');
    52                  for (let line of lines) {
    53                      if (true) {
    54                          logInfo('\t' + line);
    55                      }
    56                      if (line.includes('Now listening on: http')) {
    57                          resolve(line.split('Now listening on:')[1].trim());
    58                          if (!DEBUG) {
    59                              break;
    60                          }
    61                      } else if (line.includes('启动HTTP服务于')) {
    62                          resolve(line.split(/启动HTTP服务于|,/)[1].trim());
    63                          if (!DEBUG) {
    64                              break;
    65                          }
    66                      } else if (line.startsWith('[ERRO]')) {
    67                          reject(new Error(`start zd server failed, error: ${line.substring('[ERRO]'.length)}`));
    68                          if (!DEBUG) {
    69                              break;
    70                          }
    71                      }
    72                  }
    73              });
    74              cmd.on('error', spawnError => {
    75                  logErr('>>> start zd server failed with error', spawnError);
    76                  reject(spawnError)
    77              });
    78          });
    79      }
    80  
    81      return new Promise((resolve, reject) => {
    82          const cwd = process.env.SERVER_CWD_PATH || path.resolve(app.getAppPath(), '../');
    83          logInfo(`>> starting zd development server from source with command "go run cmd/server/main.go -p ${portServer}" in "${cwd}"`);
    84          const cmd = spawn('go', ['run', 'main.go', '-p', portServer], {
    85              cwd,
    86              shell: true,
    87          });
    88          cmd.on('close', (code) => {
    89              logInfo(`>> zd server closed with code ${code}`);
    90              _zdProcess = null;
    91          });
    92          cmd.stdout.on('data', data => {
    93              const dataString = String(data);
    94              const lines = dataString.split('\n');
    95              for (let line of lines) {
    96                  if (DEBUG) {
    97                      logInfo('\t' + line);
    98                  }
    99                  if (line.includes('Now listening on: http')) {
   100                      resolve(line.split('Now listening on:')[1].trim());
   101                      if (!DEBUG) {
   102                          break;
   103                      }
   104                  } else if (line.startsWith('[ERRO]')) {
   105                      reject(new Error(`start zd server failed, error: ${line.substring('[ERRO]'.length)}`));
   106                      if (!DEBUG) {
   107                          break;
   108                      }
   109                  }
   110              }
   111          });
   112          cmd.on('error', spawnError => {
   113              console.error('>>> start zd server failed with error', spawnError);
   114              reject(spawnError)
   115          });
   116          _zdProcess = cmd;
   117      });
   118  }
   119  
   120  export function killZdServer() {
   121      if (!IS_WINDOWS_OS) {
   122          logInfo(`>> not windows`);
   123  
   124          const cmd = `ps -ef | grep ${uuid} | grep -v "grep" | awk '{print $2}' | xargs -r kill -9`
   125          logInfo(`>> exit cmd: ${cmd}`);
   126  
   127          const cp = require('child_process');
   128          cp.exec(cmd, function (error, stdout, stderr) {
   129              logInfo(`>> exit result: stdout: ${stdout}; stderr: ${stderr}; error: ${error}`);
   130          });
   131      } else {
   132          const cmd = 'WMIC path win32_process  where "Commandline like \'%%' + uuid + '%%\'" get Processid,Caption';
   133          logInfo(`>> list process cmd: ${cmd}`);
   134  
   135          const stdout = execSync(cmd, {windowsHide: true}).toString().trim()
   136          logInfo(`>> list process result: exec ${cmd}, stdout: ${stdout}`)
   137  
   138          let pid = 0
   139          const lines = stdout.split('\n')
   140          lines.forEach(function(line){
   141              line = line.trim()
   142              console.log(`<${line}>`)
   143              logInfo(`<${line}>`)
   144              const cols = line.split(/\s/)
   145  
   146              if (line.indexOf('server') > -1) {
   147                  const col3 = cols[cols.length-1].trim()
   148                  console.log(`col3=${col3}`);
   149                  logInfo(`col3=${col3}`)
   150  
   151                  if (col3 && parseInt(col3, 10)) {
   152                      pid = parseInt(col3, 10)
   153                  }
   154              }
   155          });
   156  
   157          if (pid && pid > 0) {
   158              const killCmd = `taskkill /F /pid ${pid}`
   159              logInfo(`>> exit cmd: exec ${killCmd}`)
   160  
   161              const out = execSync(`taskkill /F /pid ${pid}`, {windowsHide: true}).toString().trim()
   162              logInfo(`>> exit result: ${out}`)
   163          }
   164      }
   165  }