Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions server/src/modules/instance/InstanceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,11 @@ export class InstanceManager extends EventEmitter {
if (event === 'terminal-output') {
this.emit('instance-output', { id, data: data.data })
} else if (event === 'terminal-exit') {
// 防止旧终端会话的退出事件覆盖新会话的状态
if (instance.terminalSessionId !== terminalSessionId) {
this.logger.info(`忽略旧终端会话退出事件: ${terminalSessionId} (当前: ${instance.terminalSessionId})`)
return
}
this.logger.info(`实例 ${instance.name} 终端会话退出`)
instance.status = 'stopped'
instance.pid = undefined
Expand All @@ -578,6 +583,10 @@ export class InstanceManager extends EventEmitter {
this.emit('instance-status-changed', { id, status: 'stopped' })
this.saveInstances()
} else if (event === 'terminal-error') {
if (instance.terminalSessionId !== terminalSessionId) {
this.logger.info(`忽略旧终端会话错误事件: ${terminalSessionId} (当前: ${instance.terminalSessionId})`)
return
}
this.logger.error(`实例 ${instance.name} 终端错误:`, data.error)
instance.status = 'error'
instance.pid = undefined
Expand Down Expand Up @@ -619,6 +628,7 @@ export class InstanceManager extends EventEmitter {
workingDirectory: instance.workingDirectory,
enableStreamForward: instance.enableStreamForward || false,
programPath: instance.programPath || '',
autoCloseOnForwardExit: instance.enableStreamForward || false,
terminalUser: instance.terminalUser
})

Expand Down
58 changes: 40 additions & 18 deletions server/src/modules/terminal/TerminalManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,16 +641,37 @@ export class TerminalManager {
this.logger.info(`参数列表: ${JSON.stringify(args)}`)

// 启动目标程序进程
const forwardProcess = spawn(executablePath, args, {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: session.workingDirectory,
env: {
...process.env,
TERM: 'xterm-256color',
COLORTERM: 'truecolor'
},
detached: os.platform() !== 'win32' // 在非Windows平台创建独立进程组
})
// 在Windows上使用PTY包装,避免stdout块缓冲导致输出不实时
let forwardProcess: ChildProcess
if (os.platform() === 'win32' && this.ptyPath) {
const ptyArgs = [
'-dir', session.workingDirectory,
'-size', '100,30',
'-coder', 'UTF-8',
'-cmd', JSON.stringify([executablePath, ...args])
]
this.logger.info(`使用PTY包装转发进程以避免stdout缓冲: ${this.ptyPath}`)
forwardProcess = spawn(this.ptyPath, ptyArgs, {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: session.workingDirectory,
env: {
...process.env,
TERM: 'xterm-256color',
COLORTERM: 'truecolor'
}
})
} else {
forwardProcess = spawn(executablePath, args, {
stdio: ['pipe', 'pipe', 'pipe'],
cwd: session.workingDirectory,
env: {
...process.env,
TERM: 'xterm-256color',
COLORTERM: 'truecolor'
},
detached: os.platform() !== 'win32' // 在非Windows平台创建独立进程组
})
}

session.streamForwardProcess = forwardProcess

Expand Down Expand Up @@ -728,14 +749,16 @@ export class TerminalManager {
sessionId: session.id,
data: exitMessage
})

// 如果配置了自动关闭,且转发进程异常退出,则关闭整个终端会话
if (session.autoCloseOnForwardExit && (code !== 0 || signal)) {

session.streamForwardProcess = undefined

// 如果配置了自动关闭,则在转发进程退出后关闭终端会话
if (session.autoCloseOnForwardExit) {
session.socket.emit('terminal-output', {
sessionId: session.id,
data: `\r\n[转发进程异常退出,正在关闭终端会话...]\r\n`
data: `\r\n[转发进程已退出,正在关闭终端会话...]\r\n`
})

// 延迟关闭,让用户看到消息
setTimeout(() => {
this.closePty(session.socket, { sessionId: session.id })
Expand All @@ -749,8 +772,6 @@ export class TerminalManager {
})
}
}

session.streamForwardProcess = undefined
})

// 处理转发进程错误
Expand Down Expand Up @@ -805,7 +826,8 @@ export class TerminalManager {
}

// 如果会话之前断开连接,现在重新连接
if (session.disconnected) {
// 仅当传入的是真实的Socket.IO socket时才替换(避免虚拟socket覆盖)
if (session.disconnected && (socket as any).connected !== undefined) {
session.disconnected = false
session.disconnectedAt = undefined
session.socket = socket
Expand Down
Loading