NodeとPythonの双方向通信実装コード

NodeとPythonの双方向通信実装コード

サードパーティのデータ サプライヤーはデータと Python を一緒にカプセル化しており、データ クエリは Python メソッドを呼び出すことによってのみ実装できます。Python メソッド呼び出しを単純な Node カプセル化によって実装できれば、すぐに起動でき、開発コストを節約できます。

最も単純かつ大雑把な通信方法は、Nodejs が Python スクリプトを呼び出して、子プロセスの出力を取得することです。ただし、Python を起動してその都度データ パケットをロードするプロセスは比較的長いため、このプロセスは最適化されています。

プロセスコミュニケーション

インデックス.py

# カプセル化された Python パッケージ、サイズが大きい from mb import MB
# データパケットからのクエリ mbe.get('1.0.1.0')

インデックス

const { spawn } = require('child_process');
python3 を ls で生成します。

ls.stdout.on('データ', (データ) => {
  console.log(`stdout: ${data}`);
});

ls.stderr.on('データ', (データ) => {
  コンソールエラー(`stderr: ${data}`);
});

ls.on('close', (コード) => {
  console.log(`子プロセスはコード $[code] で終了しました`);
});

child_process.spawn を使用して Python サブプロセスを生成し、stdout 出力をリッスンします。上記の方法は公式ドキュメントの例でもあります。現在、この例には 2 つの問題があります。

  • NodejsはPythonにデータを送信しません
  • Nodejs 呼び出しが完了すると、Python サブプロセスは終了します。次のクエリでは、Python コマンドを再度呼び出してファイルをロードし、データをクエリする必要があります。メモリを一度ロードして複数回使用することはできません。

プロセス間の双方向通信

データを一度ロードして複数回使用できることを保証するための前提は、Python プロセスが開始後に終了できないことです。 Python プロセスが終了する理由は、何もすることがないからなので、一般的な方法としては、ループ、スリープ、ポートのリッスンなどがあります。これらの方法は、同期ブロッキングタスクと同期ノンブロッキングタスクに変換できます。このうち最もコストがかからないのは、同期ノンブロッキングタスクです。すると、Linux の select と epoll が考えられます。Python の epoll を簡単に検索したところ、ネイティブパッケージがあるようです。

index.py - epoll 経由で stdin をリッスンします

インポートシステム
fcntl をインポートする
インポート選択
mbからインポートMB
jsonをインポート

mbe = MB('./データ')

# epoll モデル fd = sys.stdin.fileno()
epoll = select.epoll()
epoll.register(fd、select.EPOLLIN) 関数は、

試す:
    真の場合:
        events = epoll.poll(10) # 同期非ブロッキングデータ = ''
        fileno、events 内の event の場合:
            data += sys.stdin.readline() # data == '' または data == '\n' の場合、標準入力からデータを取得します。
                続く
            items = xxx # アイテム内のアイテムの数値処理:
                結果 = mbe.get(アイテム)
                sys.stdout.write(json.dumps(result, ensure_ascii=False) +'\n') # 標準出力に書き込むsys.stdout.flush() # バッファを更新最後に:
    epoll.unregister(fd)
    epoll.close()

index.js - stdin 経由でデータを送信する

定数 child_process = require('child_process');
python3 の子プロセスを作成します。

コールバックを [] とします。 
    チャンク=Buffer.alloc(0), 
    チャンクArr = [], 
    データ = ''、 
    onwork = false; // バッファは動的に拡張できません child.stdout.on('data', (chunk) => {
    chunkArr.push(チャンク)
    if (onwork) 戻り値;
    オンワーク = true;
    while(chunkArr.length) {
        チャンク = Buffer.concat([チャンク、chunkArr.pop()]);
        定数長さ = チャンク.長さ;
        trunkAt = -1 とします。
        for(const [k, d] of chunks.entries()) {
            if (d == '0x0a') { // 0a で終了 data += chunks.slice(trunkAt+1, trunkAt=k);
                const cb = コールバック.shift();
                cb(null, データ === 'null' ? null : データ )
                データ = '';
            }
        }
        トランクサイズ < 長さの場合
            チャンク = chunks.slice(trunkAt+1)
        }
    }
    オンワーク = false;
})

間隔を設定する(() => {
    if (callbacks.length) child.stdin.write(`\n`); // Nodejs 側には標準入出力のフラッシュメソッドがないので、ハックを使うしかありません。Python は書き込み後に最新のデータを間に合うように取得できません。}, 500)

exports.getMsg = 関数 getMsg(ip, cb) {
    コールバック.push(cb)
    child.stdin.write(`${ip}\n`); // 子プロセスの標準入力にデータを書き込みます}

Python と Nodejs は stdio を介して通信します。Python は、メモリ常駐と長期操作を実現するために、epoll を介して stdin をリッスンします。

問題

  • Nodejs は実行結果として標準出力を使用するため、Python 側では追加の印刷情報なしで実行結果を標準出力に書き込むことしかできません。
  • Nodejs 側の標準入力には flush メソッドがないため、Python 側でのイベントトリガーがタイムリーではありません。現在は、Nodejs 側で定期的に空の情報を送信するというハックが実装されています。
  • バッファは動的に拡張できず、C言語のポインタほど便利ではなく、stdoutを解析するときに見苦しいです。

要約する

Nodejs と Python 間の双方向通信は実現できますが、前述の問題のため、この方法はここでは推奨されません。HTTP または Socket の方がはるかに優れています。

NodejsとPythonの双方向通信の実装コードに関するこの記事はこれで終わりです。NodejsとPythonの双方向通信に関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 現在のタイムスタンプを生成する Python と Node.js の例
  • Node.js と Python のどちらを選択すべきでしょうか?
  • Node.js と Python で書かれたシンプルな HTTP 静的ファイル サーバー
  • Node.js、PHP、Python の文字処理パフォーマンスの比較

<<:  Docker を使用して nginx で tomcat クラスターを構築する方法 (画像とテキスト付き)

>>:  MYSQL トランザクション チュートリアル Yii2.0 マーチャント引き出し機能

推薦する

Hyper-V インストール CentOS 8 の問題の分析

CentOS 8 がリリースされてから随分経ちました。Linux 仮想マシンをいじっている人間として...

MySQLでレコードを変更する場合、更新操作フィールド = フィールド + 文字列

シナリオによっては、varchar 型のフィールドを変更する必要があり、変更の結果は 2 つのフィー...

jQuery Ajax チャットボットの実装事例

チャットボットは多くの手作業を省くことができ、顧客サービス、天気予報対応など、さまざまな状況で使用で...

js+ca​​nvas でコードレイン効果を実現

この記事では、js+ca​​nvasコードの雨効果の具体的なコードを参考までに共有します。具体的な内...

フォーム要素属性の読み取り専用と無効の使用の比較

1) 適用範囲:読み取り専用:input[type="text"],input[...

Tomcatのサーバーオプションの詳細な説明

1. 構成デフォルトでは、最初の 2 つはチェックされていないので、チェックする必要があります。 (...

最新の超詳細な VMware 仮想マシンのダウンロードとインストールのグラフィック チュートリアル

目次1. 仮想マシンをダウンロードする2. 仮想マシンのインストールVMware のダウンロードとイ...

MySQL における引用符とバックティックの違いと使い方の詳細な説明

序文そこでこのブログを書きました。このブログでは大物の記事からいくつかの知識も推奨しています。侵害が...

CSS3 rgb と rgba (透明色) の使い方の詳しい説明

誰もが色にとても敏感だと思います。私たちの目が見るところにはどこにでも色があります。では、CSS で...

CSS ピックアップ矢印、カタログ、アイコン実装コード

1. CSS その他のアイコンアイコンを作成するには 3 つの方法があります。写真css (小さな矢...

MySQL5.7.03 上位バージョンから MySQL 5.7.17 への置き換えインストール プロセスと見つかった問題の解決策

1. インストール方法は? 1. [実行] -> [cmd] と入力して、小さな黒いウィンドウ...

MySQL で JSON 形式のフィールドをクエリする詳細な説明

作業開発プロセス中に、顧客の名前、携帯電話番号、ID カード、およびドキュメントの種類を動的に保存す...

MySQLデータのバックアップ方法の選択と考え方

目次1. rsync、cpでファイルをコピーする2. xxxをoutfile構文に選択する3. 遅延...

OpenLayers 3 のベクターマップソースの読み込みの問題を解決する

1. ベクターマップベクター グラフィックスは直線と曲線を使用してグラフィックスを表します。これらの...

HTML はテキストの外側に省略記号を表示します...テキストオーバーフローによって実装されます

div または span に同時に CSS を適用する必要があります。コードをコピーコードは次のとお...