diff --git a/launcher/NapCatWinBootMain.exe b/launcher/NapCatWinBootMain.exe index 66f69e09..99a69b9e 100644 Binary files a/launcher/NapCatWinBootMain.exe and b/launcher/NapCatWinBootMain.exe differ diff --git a/src/shell/pipe.ts b/src/shell/pipe.ts index bde201cd..1f2375df 100644 --- a/src/shell/pipe.ts +++ b/src/shell/pipe.ts @@ -1,6 +1,7 @@ import { LogWrapper } from '@/common/log'; import * as net from 'net'; import * as process from 'process'; +import { Writable } from 'stream'; /** * 连接到命名管道并重定向stdout @@ -25,12 +26,50 @@ export function connectToNamedPipe(logger: LogWrapper, timeoutMs: number = 5000) }, timeoutMs); try { - let originalStdoutWrite = process.stdout.write.bind(process.stdout); + const originalStdoutWrite = process.stdout.write.bind(process.stdout); const pipeSocket = net.connect(pipePath, () => { // 清除超时 clearTimeout(timeoutId); + // 优化网络性能设置 + pipeSocket.setNoDelay(true); // 减少延迟 + + // 设置更高的高水位线,允许更多数据缓冲 + logger.log(`[StdOut] 已重定向到命名管道: ${pipePath}`); + + // 创建拥有更优雅背压处理的 Writable 流 + const pipeWritable = new Writable({ + highWaterMark: 1024 * 64, // 64KB 高水位线 + write(chunk, encoding, callback) { + if (!pipeSocket.writable) { + // 如果管道不可写,退回到原始stdout + logger.log('[StdOut] 管道不可写,回退到控制台输出'); + return originalStdoutWrite(chunk, encoding, callback); + } + + // 尝试写入数据到管道 + const canContinue = pipeSocket.write(chunk, encoding, () => { + // 数据已被发送或放入内部缓冲区 + }); + + if (canContinue) { + // 如果返回true,表示可以继续写入更多数据 + // 立即通知写入流可以继续 + process.nextTick(callback); + } else { + // 如果返回false,表示内部缓冲区已满 + // 等待drain事件再恢复写入 + pipeSocket.once('drain', () => { + callback(); + }); + } + // 明确返回true,表示写入已处理 + return true; + } + }); + + // 重定向stdout process.stdout.write = ( chunk: any, encoding?: BufferEncoding | (() => void), @@ -40,8 +79,11 @@ export function connectToNamedPipe(logger: LogWrapper, timeoutMs: number = 5000) cb = encoding; encoding = undefined; } - return pipeSocket.write(chunk, encoding as BufferEncoding, cb); + + // 使用优化的writable流处理写入 + return pipeWritable.write(chunk, encoding as BufferEncoding, cb as () => void); }; + // 提供断开连接的方法 const disconnect = () => { process.stdout.write = originalStdoutWrite; @@ -53,6 +95,7 @@ export function connectToNamedPipe(logger: LogWrapper, timeoutMs: number = 5000) resolve({ disconnect }); }); + // 管道错误处理 pipeSocket.on('error', (err) => { clearTimeout(timeoutId); process.stdout.write = originalStdoutWrite; @@ -60,11 +103,18 @@ export function connectToNamedPipe(logger: LogWrapper, timeoutMs: number = 5000) reject(err); }); + // 管道关闭处理 pipeSocket.on('end', () => { process.stdout.write = originalStdoutWrite; logger.log('命名管道连接已关闭'); }); + // 确保在连接意外关闭时恢复stdout + pipeSocket.on('close', () => { + process.stdout.write = originalStdoutWrite; + logger.log('命名管道连接已关闭'); + }); + } catch (error) { clearTimeout(timeoutId); logger.log(`尝试连接命名管道 ${pipePath} 时发生异常:`, error);