首页 > 解决方案 > Node.JS:在接收到标准输出数据后写入子进程生成

问题描述

我正在尝试做的事情:我用 C++ 编写了一个国际象棋引擎,并将其编译为可执行文件。我现在使用 Node.JS 让这个引擎与国际象棋网站的 API 进行通信(以便人类和其他引擎可以挑战它)。

我正在使用 Node.JS 的child_process模块来创建一个spawn促进 API 和引擎之间的 I/O 通信的模块。

为了告诉引擎一个新游戏已经开始,我写"UCI\n"了这个过程。然后我等待引擎输出"id name {engine name}\r\nid author {my name}\r\nuciok\r\n"。从我的引擎接收到这个输出后,我需要写"isready\n"回它,以便它稍后可以开始生成动作。

的问题:我面临的问题是,在我最初"UCI\n"写入进程之后,我调用child_process.spawn().stdin.end(). 似乎这个end()调用必须存在于某个地方,否则我的进程不会接收到我正在写给它的输入。

每当我在收到引擎的输出后尝试写入"isready\n"子进程时,都会遇到以下错误:

错误 [ERR_STREAM_WRITE_AFTER_END]:结束后写入

整个事情看起来像这样:

const engineExePath = 'C:\\Users\\chopi\\Desktop\\chess-engine\\maestro\\uci.exe';
const childProcess = require('child_process');
const spawn_options = {
    cwd: null, env: null, detached: false
}

const engineStream = childProcess.spawn(engineExePath, [], spawn_options);
engineStream.stdout.on('data', function (data) {

    var result = data.toString();

    if (result == 'id name Maestro\r\nid author dvdutch\r\nuciok\r\n') {
        //Here, we are listening to the response from the engine, and are now ready to spit back a message to it.
        //This is where the error is occurring
        engineStream.stdin.write('isready\n');
    } else {
        console.log('no match');
    }

});

engineStream.stdin.write('uci\n');
engineStream.stdin.end();

我尝试过的:engineStream.stdin.end()当子进程通过以下方式关闭其流时,我尝试调用:

engineStream.on('close', (code) => {
  engineStream.stdin.end();
});

但是,当我这样做时,我的 Node 文件和我的子进程之间似乎没有任何通信,有点像engineStream.stdin.end()根本没有被调用的时候。与此方法的整个集成看起来像这样:

const engineExePath = 'C:\\Users\\chopi\\Desktop\\chess-engine\\maestro\\uci.exe';
const childProcess = require('child_process');
const spawn_options = {
    cwd: null, env: null, detached: false
}

const engineStream = childProcess.spawn(engineExePath, [], spawn_options);
engineStream.stdout.on('data', function (data) {

    var result = data.toString();

    if (result == 'id name Maestro\r\nid author dvdutch\r\nuciok\r\n') {
        //Here, we are listening to the response from the engine, and are now ready to spit back a message to it.
        engineStream.stdin.write('isready\n');
    } else {
        console.log('no match');
    }

});

engineStream.on('close', (code) => {
  engineStream.stdin.end();
});

engineStream.stdin.write('uci\n');

我想知道的是: 在我的子进程和我的节点文件之间促进这种消息乒乓的正确方法是什么?

标签: javascriptnode.jsiochild-process

解决方案


推荐阅读