關於如何實現 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(`spawn`, () => { |
子程序初始化後,就可以透過python.stdin.write() 向其傳送資料。
在呼叫 child_process.spawn 時設定一個環境變數,即在上述選項物件中設定 env: { key: "value" }。
3、讀取 Python 子程序的響應
接下來,我們需要讀取 Python 指令碼的響應。讓我們開始吧:
import nexline from 'nexline'; <font>// Put this import at the top of the file<i> |
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 |