【问题标题】:Problems communicating between Node.js and Python via stdio通过 stdio 在 Node.js 和 Python 之间进行通信的问题
【发布时间】:2012-08-07 22:12:55
【问题描述】:

我正在从 Python 线程中生成一个 Node 进程,并通过 stdio 在它们之间传递数据。在 Python 向 Node 发送某些内容后,Node 会启动一个子进程,然后将该子进程的输出发送回 Python。

这有效,几秒钟后没有更多数据出现。但是,如果我终止 Node 进程,那么突然间所有数据都会同时出现。

我认为这与缓冲有关,但我尝试了很多方法,但无法使其正常工作。

值得一提的是,如果我在 Python 之外运行监视器,它可以正常工作,所以这可能是 Python 方面的问题。

相关Python代码:

class MonitorThread(Thread):
    # *snip*

    def run(self):
        self.process = Popen(['node',
            path.join(PACKAGE_PATH 'monitor.js')],
            stdout=PIPE, stdin=PIPE, stderr=PIPE)

        while self.process.poll() is None:
            stdout = self.process.stdout.readline().rstrip('\n')

            if stdout:
                main_thread(debug, stdout)

            stderr = self.process.stderr.readline().rstrip('\n')

            if stderr:
                main_thread(debug, stderr)

            #time.sleep(0.1)

相关的 Node.js 代码(在 CoffeeScript 中,但即使您不知道也可以理解):

# *snip*

child = spawn cmd, options

child.stdout.on 'data', (data) ->
    process.stdout.write "stdout: #{data.toString().trim()}\n"

child.stderr.on 'data', (data) ->
    process.stdout.write "stderr: #{data.toString().trim()}\n"

还有很多其他代码,但它们并不真正相关,正在发送数据,然后接收数据,只是片刻。它仍在运行,当我手动杀死它时,其余数据突然出现。

Monitor [send] - {"wrap": false, "directories": {"src": "lib"}, "id": 0, "base_dir": "C:\\Users\\Joe\\Documents\\GitHub\\CoffeeScript-Sublime-Plugin"}
Monitor [recv] - 13:55:30 - compiled src\a.coffee
Monitor [recv] - path.exists is now called `fs.exists`.
Monitor [recv] - 13:55:30 - compiled src\b.coffee
  • 我试过 util.pump()
  • 我已尝试使用 spawn() 调用 stdio: 'inherit'
  • 我已尝试在发送更多数据之前等待 'drain' 事件。

【问题讨论】:

  • 似乎输出被缓冲了。这可能有助于防止缓冲:stackoverflow.com/questions/6471004/…
  • 这似乎没有什么区别,实际上它加剧了问题。只有一行通过而不是三行,当然,当现在终止进程时,什么也没有通过(因为缺乏缓冲)。
  • 似乎我还有标准输入输出:'继承'。删除它后,我得到: EBADF - 错误的文件描述符。编辑:如果独立运行,我明白了。如果从 Python 中运行,我不会收到错误但没有输出。

标签: javascript python node.js coffeescript subprocess


【解决方案1】:

您还应该传递end 事件来关闭流并让节点刷新它们:

child = spawn cmd, options

child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stdout)

child.stdout.on 'data', (data) ->
    process.stdout.write "stdout: #{data.toString().trim()}\n"

child.stdout.on 'end', () ->
    process.stdout.end()

child.stderr.on 'end', () ->
    process.stdout.end()

更好的选择是使用Stream.pipe()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-28
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    相关资源
    最近更新 更多