2025-02-23 02:11:17 +08:00
|
|
|
import ServerService from "./ServerService";
|
2025-02-25 11:57:54 +08:00
|
|
|
import VersionRepository from "../repository/VersionRepository";
|
2025-02-23 02:11:17 +08:00
|
|
|
import PathUtils from "../utils/PathUtils";
|
|
|
|
import GlobalConstant from "../core/GlobalConstant";
|
2025-02-25 11:57:54 +08:00
|
|
|
import { app, BrowserWindow, Notification } from "electron";
|
2025-02-24 14:35:11 +08:00
|
|
|
import treeKill from "tree-kill";
|
2025-02-25 11:57:54 +08:00
|
|
|
import BeanFactory from "../core/BeanFactory";
|
2025-02-25 14:15:18 +08:00
|
|
|
import ResponseUtils from "../utils/ResponseUtils";
|
2025-02-25 23:01:57 +08:00
|
|
|
import { BusinessError, ResponseCode } from "../core/BusinessError";
|
2025-02-26 11:49:55 +08:00
|
|
|
import Logger from "../core/Logger";
|
2025-02-23 02:11:17 +08:00
|
|
|
|
2025-02-23 21:07:44 +08:00
|
|
|
class FrpcProcessService {
|
2025-02-23 02:11:17 +08:00
|
|
|
private readonly _serverService: ServerService;
|
2025-02-25 11:57:54 +08:00
|
|
|
private readonly _versionDao: VersionRepository;
|
2025-02-23 02:11:17 +08:00
|
|
|
private _frpcProcess: any;
|
2025-02-24 14:35:11 +08:00
|
|
|
private _frpcProcessListener: any;
|
2025-02-26 11:49:55 +08:00
|
|
|
private _frpcLastStartTime: number = -1;
|
2025-02-23 02:11:17 +08:00
|
|
|
|
2025-02-25 11:57:54 +08:00
|
|
|
constructor(serverService: ServerService, versionDao: VersionRepository) {
|
2025-02-23 02:11:17 +08:00
|
|
|
this._serverService = serverService;
|
|
|
|
this._versionDao = versionDao;
|
|
|
|
}
|
|
|
|
|
|
|
|
isRunning(): boolean {
|
2025-02-24 14:35:11 +08:00
|
|
|
if (!this._frpcProcess) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
try {
|
2025-02-26 16:12:11 +08:00
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.isRunning`,
|
|
|
|
`pid: ${this._frpcProcess.pid}`
|
|
|
|
);
|
2025-02-24 14:35:11 +08:00
|
|
|
process.kill(this._frpcProcess.pid, 0);
|
|
|
|
return true;
|
|
|
|
} catch (err) {
|
|
|
|
return false;
|
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
async startFrpcProcess() {
|
2025-02-24 16:38:39 +08:00
|
|
|
if (this.isRunning()) {
|
|
|
|
return;
|
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
const config = await this._serverService.getServerConfig();
|
2025-02-24 16:38:39 +08:00
|
|
|
if (!config) {
|
2025-02-25 23:01:57 +08:00
|
|
|
throw new BusinessError(ResponseCode.NOT_CONFIG);
|
2025-02-24 16:38:39 +08:00
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
const version = await this._versionDao.findByGithubReleaseId(
|
|
|
|
config.frpcVersion
|
|
|
|
);
|
2025-02-24 16:38:39 +08:00
|
|
|
const configPath = PathUtils.getTomlConfigFilePath();
|
|
|
|
await this._serverService.genTomlConfig(configPath);
|
2025-02-24 14:35:11 +08:00
|
|
|
const command = `./${PathUtils.getFrpcFilename()} -c "${configPath}"`;
|
|
|
|
this._frpcProcess = require("child_process").spawn(command, {
|
2025-02-23 02:11:17 +08:00
|
|
|
cwd: version.localPath,
|
|
|
|
shell: true
|
|
|
|
});
|
2025-02-26 11:49:55 +08:00
|
|
|
this._frpcLastStartTime = Date.now();
|
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.startFrpcProcess`,
|
|
|
|
`start command: ${command}`
|
|
|
|
);
|
2025-02-23 21:07:44 +08:00
|
|
|
this._frpcProcess.stdout.on("data", data => {
|
2025-02-26 11:49:55 +08:00
|
|
|
Logger.debug(`FrpcProcessService.startFrpcProcess`, `stdout: ${data}`);
|
2025-02-23 02:11:17 +08:00
|
|
|
});
|
|
|
|
|
2025-02-24 14:35:11 +08:00
|
|
|
this._frpcProcess.stderr.on("data", data => {
|
2025-02-26 11:49:55 +08:00
|
|
|
Logger.debug(`FrpcProcessService.startFrpcProcess`, `stderr: ${data}`);
|
2025-02-23 02:11:17 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2025-02-24 14:35:11 +08:00
|
|
|
async stopFrpcProcess() {
|
2025-02-24 16:38:39 +08:00
|
|
|
if (this._frpcProcess && this.isRunning()) {
|
2025-02-26 11:49:55 +08:00
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.stopFrpcProcess`,
|
|
|
|
`pid: ${this._frpcProcess.pid}`
|
|
|
|
);
|
2025-02-24 14:35:11 +08:00
|
|
|
treeKill(this._frpcProcess.pid, (error: Error) => {
|
|
|
|
if (error) {
|
|
|
|
throw error;
|
|
|
|
} else {
|
|
|
|
this._frpcProcess = null;
|
2025-02-26 11:49:55 +08:00
|
|
|
this._frpcLastStartTime = -1;
|
|
|
|
|
2025-02-24 14:35:11 +08:00
|
|
|
// clearInterval(this._frpcProcessListener);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
|
2025-02-26 16:12:11 +08:00
|
|
|
async reloadFrpcProcess() {
|
|
|
|
if (!this.isRunning()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const config = await this._serverService.getServerConfig();
|
|
|
|
if (!config) {
|
|
|
|
throw new BusinessError(ResponseCode.NOT_CONFIG);
|
|
|
|
}
|
|
|
|
const version = await this._versionDao.findByGithubReleaseId(
|
|
|
|
config.frpcVersion
|
|
|
|
);
|
|
|
|
const configPath = PathUtils.getTomlConfigFilePath();
|
|
|
|
await this._serverService.genTomlConfig(configPath);
|
|
|
|
const command = `./${PathUtils.getFrpcFilename()} reload -c "${configPath}"`;
|
|
|
|
require("child_process").exec(
|
|
|
|
command,
|
|
|
|
{
|
|
|
|
cwd: version.localPath,
|
|
|
|
shell: true
|
|
|
|
},
|
|
|
|
(error, stdout, stderr) => {
|
|
|
|
if (error) {
|
|
|
|
Logger.error(`FrpcProcessService.reloadFrpcProcess`, error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (stderr) {
|
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.reloadFrpcProcess`,
|
|
|
|
`stderr: ${stderr}`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.reloadFrpcProcess`,
|
|
|
|
`stderr: ${stdout}`
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-02-23 02:11:17 +08:00
|
|
|
watchFrpcProcess(listenerParam: ListenerParam) {
|
2025-02-24 14:35:11 +08:00
|
|
|
this._frpcProcessListener = setInterval(() => {
|
2025-02-23 02:11:17 +08:00
|
|
|
const running = this.isRunning();
|
|
|
|
// todo return status to view.
|
|
|
|
// logDebug(
|
|
|
|
// LogModule.FRP_CLIENT,
|
|
|
|
// `Monitoring frpc process status: ${status}, Listener ID: ${frpcStatusListener}`
|
|
|
|
// );
|
2025-02-26 11:49:55 +08:00
|
|
|
Logger.debug(
|
|
|
|
`FrpcProcessService.watchFrpcProcess`,
|
|
|
|
`running: ${running}`
|
|
|
|
);
|
2025-02-23 02:11:17 +08:00
|
|
|
if (!running) {
|
2025-02-26 11:49:55 +08:00
|
|
|
if (this._frpcLastStartTime !== -1) {
|
|
|
|
new Notification({
|
|
|
|
title: app.getName(),
|
|
|
|
body: "Connection lost, please check the logs for details."
|
|
|
|
}).show();
|
|
|
|
}
|
2025-02-23 02:11:17 +08:00
|
|
|
// logError(
|
|
|
|
// LogModule.FRP_CLIENT,
|
|
|
|
// "Frpc process status check failed. Connection lost."
|
|
|
|
// );
|
2025-02-24 14:35:11 +08:00
|
|
|
// clearInterval(this._frpcProcessListener);
|
2025-02-23 02:11:17 +08:00
|
|
|
}
|
2025-02-25 11:57:54 +08:00
|
|
|
const win: BrowserWindow = BeanFactory.getBean("win");
|
|
|
|
win.webContents.send(
|
2025-02-24 14:35:11 +08:00
|
|
|
listenerParam.channel,
|
2025-02-25 12:37:16 +08:00
|
|
|
ResponseUtils.success(running)
|
2025-02-24 14:35:11 +08:00
|
|
|
);
|
2025-02-23 02:11:17 +08:00
|
|
|
}, GlobalConstant.FRPC_PROCESS_STATUS_CHECK_INTERVAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-23 21:07:44 +08:00
|
|
|
export default FrpcProcessService;
|