繁体   English   中英

如何用nodejs写process.stdin

[英]How to write on process.stdin with nodejs

当我尝试写入我用 child_process 的 spawn function 生成的进程的 stdin 时,nodejs 出现问题

const spawn = require("child_process").spawn;
class Barotrauma {
  static instance = null;
  server = null;

  constructor() {
    this.server = spawn(
      "F:\\dev\\barotrauma\\steamcmd\\steamapps\\common\\Barotrauma Dedicated Server\\DedicatedServer.exe",
      {
        stdio: [process.stdin, process.stdout, process.stderr],
      }
    );
  }
  static getInstance() {
    if (Barotrauma.instance === null) {
      Barotrauma.instance = new Barotrauma();
    } else {
      return Barotrauma.instance;
    }
  }

  sendCommand(command) {
    //this.server.stdout.write(`${command}\n`)
    // this is a test to get an output on command execution to see if it works
    process.stdin.write("help\n");
  }
}

module.exports = Barotrauma;

因此,这段代码用于启动游戏服务器,然后在套接字事件上向其发送命令(套接字调用 sendCommand 函数)

如果我尝试在控制台中编写命令它工作正常,但如果我尝试执行 sendCommand function 它会崩溃并出现错误:

node:events:498
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writeGeneric (node:internal/stream_base_commons:151:3)
    at ReadStream.Socket._writeGeneric (node:net:795:11)
    at ReadStream.Socket._write (node:net:807:8)
    at writeOrBuffer (node:internal/streams/writable:389:12)
    at _write (node:internal/streams/writable:330:10)
    at ReadStream.Writable.write (node:internal/streams/writable:334:10)
    at Barotrauma.sendCommand (F:\dev\barotrauma\serverManager.js:26:19)
    at handleReward (F:\dev\barotrauma\handler.js:4:28)
    at WebSocket.connection.onmessage (F:\dev\barotrauma\index.js:26:5)
Emitted 'error' event on ReadStream instance at:
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  errno: -4047,
  code: 'EPIPE',
  syscall: 'write'
}

崩溃似乎源于 process.stin.write function。

知道如何解决这个问题吗?

您可能想参考options.stdio

如果不进一步深入了解整个上下文,就很难说出到底发生了什么,但以下内容可能会如您所料:

如果您确实需要连接父 fds 和子 fds,您可以使用pipe作为stdio选项,并在两个进程之间传播数据。

以下代码段(减少以最大限度地减少噪音)应该可以解决问题:

class Barotrauma {
  server = null;

  constructor() {
    // Default `stdio` option is `pipe` for fds 0, 1 and 2 (stdio, stdout and stderr)
    this.server = spawn(
      "F:\\dev\\barotrauma\\steamcmd\\steamapps\\common\\Barotrauma Dedicated Server\\DedicatedServer.exe"
    );

    // Catches incoming messages from child, if necessary
    this.server.stdout.on('data', (d) => {
      console.log(`Message from child: '${d}'`)
    })
  }

  sendCommand(cmd) {
    // Sends messages to child
    this.server.stdin.write(`${cmd}\n`);
  }
}

鉴于您处于 Windows 环境中,请注意,如果您需要异步 I/O 与该应用程序通信,您可能希望使用overlapped而不是pipe 有关详细信息,请参阅官方文档

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM