调整C端展示
This commit is contained in:
@@ -206,39 +206,109 @@ class JavaRunner {
|
||||
* 停止 Spring Boot 应用
|
||||
*/
|
||||
stopSpringBoot() {
|
||||
return new Promise((resolve) => {
|
||||
return new Promise(async (resolve) => {
|
||||
const { exec } = require('child_process');
|
||||
const killedPids = new Set();
|
||||
let killAttempts = 0;
|
||||
|
||||
// 方法1: 如果有进程引用,通过PID杀死
|
||||
if (this.springBootProcess && !this.springBootProcess.killed) {
|
||||
// 设置3秒超时,如果进程没有正常退出,强制kill
|
||||
const timeout = setTimeout(() => {
|
||||
console.log('[Java] Force killing Spring Boot process');
|
||||
try {
|
||||
this.springBootProcess.kill('SIGKILL');
|
||||
} catch (e) {
|
||||
console.error('[Java] Error force killing:', e);
|
||||
const pid = this.springBootProcess.pid;
|
||||
console.log('[Java] Method 1: Stopping Spring Boot by PID:', pid);
|
||||
|
||||
// 使用 /F 强制终止,/T 终止子进程树
|
||||
const killCommand = `taskkill /F /T /PID ${pid}`;
|
||||
console.log('[Java] Executing:', killCommand);
|
||||
|
||||
exec(killCommand, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.error('[Java] taskkill by PID failed:', error);
|
||||
} else {
|
||||
console.log('[Java] taskkill by PID success:', stdout);
|
||||
killedPids.add(pid);
|
||||
}
|
||||
|
||||
// 清理端口记录文件
|
||||
this.cleanupJavaPortFile();
|
||||
resolve();
|
||||
}, 3000);
|
||||
|
||||
this.springBootProcess.on('close', () => {
|
||||
clearTimeout(timeout);
|
||||
console.log('[Java] Spring Boot application stopped gracefully');
|
||||
|
||||
// 清理端口记录文件
|
||||
this.cleanupJavaPortFile();
|
||||
resolve();
|
||||
killAttempts++;
|
||||
checkComplete();
|
||||
});
|
||||
|
||||
// 先尝试优雅关闭
|
||||
console.log('[Java] Sending SIGTERM to Spring Boot');
|
||||
this.springBootProcess.kill('SIGTERM');
|
||||
} else {
|
||||
// 即使没有进程引用,也尝试清理端口记录文件
|
||||
this.cleanupJavaPortFile();
|
||||
resolve();
|
||||
killAttempts++;
|
||||
}
|
||||
|
||||
// 方法2: 通过端口杀死占用进程(精确定位,不会误杀其他Java进程)
|
||||
const recordedPort = this.currentJavaPort || this.getRecordedJavaPort();
|
||||
if (recordedPort) {
|
||||
console.log(`[Java] Method 2: Killing process on port ${recordedPort} (precise targeting)`);
|
||||
|
||||
// 查找占用端口的进程
|
||||
const findCommand = `netstat -ano | findstr :${recordedPort}`;
|
||||
exec(findCommand, (error, stdout) => {
|
||||
if (!error && stdout) {
|
||||
// 提取PID(最后一列)
|
||||
const lines = stdout.trim().split('\n');
|
||||
const pids = new Set();
|
||||
|
||||
lines.forEach(line => {
|
||||
const parts = line.trim().split(/\s+/);
|
||||
const pid = parts[parts.length - 1];
|
||||
if (pid && pid !== '0' && !killedPids.has(pid)) {
|
||||
pids.add(pid);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[Java] Found PIDs on port ${recordedPort}:`, Array.from(pids));
|
||||
|
||||
if (pids.size > 0) {
|
||||
// 杀死所有找到的进程
|
||||
let portsKilled = 0;
|
||||
pids.forEach(pid => {
|
||||
exec(`taskkill /F /T /PID ${pid}`, (err, out) => {
|
||||
portsKilled++;
|
||||
if (!err) {
|
||||
console.log(`[Java] Killed process ${pid} on port ${recordedPort}`);
|
||||
} else {
|
||||
console.warn(`[Java] Failed to kill process ${pid}:`, err);
|
||||
}
|
||||
|
||||
if (portsKilled === pids.size) {
|
||||
killAttempts++;
|
||||
checkComplete();
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log(`[Java] No process found on port ${recordedPort} (already cleaned)`);
|
||||
killAttempts++;
|
||||
checkComplete();
|
||||
}
|
||||
} else {
|
||||
console.log(`[Java] No process found on port ${recordedPort}`);
|
||||
killAttempts++;
|
||||
checkComplete();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('[Java] No port recorded, skipping port-based kill');
|
||||
killAttempts++;
|
||||
}
|
||||
|
||||
// 检查是否所有清理方法都已完成
|
||||
function checkComplete() {
|
||||
const expectedAttempts = recordedPort ? 2 : 1;
|
||||
if (killAttempts >= expectedAttempts) {
|
||||
// 清理端口记录文件
|
||||
this.cleanupJavaPortFile();
|
||||
|
||||
// 等待500ms确保进程完全终止
|
||||
setTimeout(() => {
|
||||
console.log('[Java] Spring Boot stop process completed');
|
||||
console.log('[Java] Note: Other Java processes (like IDEA) are NOT affected');
|
||||
resolve();
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
// 绑定this上下文
|
||||
checkComplete = checkComplete.bind(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user