关于如何实现 Javascript/Node.js <--> Python IPC 的快速小教程。
为了促进 Javascript/Node.js Web 服务器和 Python AI 子进程之间的通信,可以使用标准输入 (stdin) 和标准输出 (stdout) 流建立进程间通信 (IPC)。
Javascript
虽然 Node.js 有一个称为 IPC 的 fanceh 消息传递系统,但在与不运行 Javascript/Node.js 的进程通信时,它实际上不起作用。为此,解决方案是使用子进程的标准输入 (stdin) 和标准输出 (stdout) 进行通信:
1、从 Node.js 生成 Python 子进程
让我们从编写父 Node.js 脚本开始。首先,我们需要生成 Python 子进程,因此我们这样做:
import { spawn } from 'child_process'; |
这将生成 Python 脚本作为子进程,并将 stdin 和 stdout 设置为“管道”模式以便进行交互,并将 stderr 设置为“继承”模式以共享父进程的错误流。
我们将 stdin 和 stdout 设置为pipe模式(这让我们可以与流交互),并将标准错误 (stderr) 设置为inherit模式,这允许它共享父进程的 stderr。这样,子进程中的错误就会向上传播,并最终出现在父进程将其输出发送到的同一个日志文件中。
2、发送数据到 Python 子进程
如果您需要向 Python 子进程发送一些数据,则必须等到它初始化后才能发送一些数据:
python.on(<code>spawn</code>, () => { |
子进程初始化后,就可以通过python.stdin.write() 向其发送数据。
在调用 child_process.spawn 时设置一个环境变量,即在上述选项对象中设置 env: { key: "value" }。
3、读取 Python 子进程的响应
接下来,我们需要读取 Python 脚本的响应。让我们开始吧:
import nexline from 'nexline'; // Put this import at the top of the file |
nexline 软件包用于通过 python.stdout 从 Python 子进程中高效地逐行读取响应。
最简单的方法是监听 python.stdout 上的数据事件,但这并不能保证到达的每个数据块实际上都是一行数据,因为进程间的数据不像在终端显示内容时那样采用行缓冲。
要解决这个问题,我建议使用我最喜欢的 npm 软件包之一:nexline。不管你信不信,以最小的缓冲来高效处理这个问题比听起来要困难得多,所以使用一个软件包来帮你解决这个问题会更容易。
通过一个漂亮的 for await...of 循环,我们可以高效地读取 Python 子进程的响应。
如果您真的要这样做,我建议将其封装在 EventEmitter(Node.js)/EventTarget(WHAT WG 浏览器规范,Node.js 也有)中。
Python 子进程
Python 脚本从 sys.stdin 读取输入,并将响应写入 sys.stdout。调用 sys.stdout.flush() 对于确保立即发送响应至关重要。
import sys |
简单!我们只需遍历 sys.stdin,即可从父 Node.js 进程中读取数据。
我们可以写入 sys.stdout,将数据发送回父进程,但重要的是要调用 sys.stdout.flush()!Node.js 没有类似的命令,因为它很聪明,但在 Python 中,除非调用 .flush() 强制它发送响应,否则它可能直到不知道什么时候(如果有的话)才会发送响应。
结论
这种方法可在 Javascript 和 Python 之间实现高效的进程间通信,使应用程序能够充分利用两种语言的优势。
我们在这里处理的是纯文本消息,建议使用 JSON
- JSON.stringify()
- JSON.parse() (Javascript)
- json.dumps()
- json.loads (Python)
来序列化/反序列化消息,以确保稳健性。
JSON 默认不包含换行符,并且会将任何存在的字符转义为 \n,因此在这种情况下应该是安全的。
完整代码:
index.mjs:
#!/usr/bin/env node |
child.py:
#!/usr/bin/env python3 |