Как общаться между node.js процесс и процесс python

#python #node.js #unix #process #wsgi

Вопрос:

У меня есть node.js процесс и процесс python, запущенный параллельно. Node.js процесс-это http-сервер. Всякий раз, когда я получаю запрос, я хочу вызвать вызываемый объект (функцию/ или любую вызываемую) в процессе python и передать некоторую переменную среды и вызываемую функцию из node.js код. В коде psudo это что-то вроде

 // node.js process
http.createServer(function (req, res) {
  function start_response(status_code, headers){
    // closure function that sets headers
    res.writeHead(status_code);
  }
  env = {
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'HTTP_HOST': '127.0.0.1:8000',
 'HTTP_CONNECTION': 'keep-alive',
  }
  // want to call the app function in the python file likr
  // response = app(env, start_response)
  // and finally
  res.write(response)
  res.end()
})
 
 # python process
def app(env, start_response):
    # do something
    start_response(200)
    return "hello"
 

Каков способ связи между этими двумя процессами? Я могу создать процесс python из node.js используя childprocess , но как передать функцию javascript в python? Как можно решить эту проблему? Заранее спасибо.

Ответ №1:

Вы можете использовать Named Pipes . Цель состоит в том, чтобы использовать именованные каналы для связи.

  1. А Node.js процесс запишет некоторые данные в канал (A)
  2. Процесс Python считывает данные из канала (A) и манипулирует данными
  3. Описанный выше процесс python затем записывает данные в канал (B)
  4. Node.js считывает данные из трубы (B)

Python: чтение, обработка и запись

Сначала давайте создадим простой процесс Python, который считывает данные из именованного канала A, обрабатывает данные, а затем записывает их в именованный канал B (для простоты функция process_msg() здесь возвращает прочитанные данные). Сценарий сначала создает именованный канал A с помощью команды os.mkfifo ().

 import os
import select

IPC_FIFO_NAME_A = "pipe_a"
IPC_FIFO_NAME_B = "pipe_b"

def get_message(fifo):
    '''Read n bytes from pipe. Note: n=24 is an example'''
    return os.read(fifo, 24)

def process_msg(msg):
    '''Process message read from pipe'''
    return msg

if __name__ == "__main__":
    os.mkfifo(IPC_FIFO_NAME_A)  # Create Pipe A

    try:
        fifo_a = os.open(IPC_FIFO_NAME_A, os.O_RDONLY | os.O_NONBLOCK)  # pipe is opened as read only and in a non-blocking mode
        print('Pipe A ready')

        while True:
            try:
                fifo_b = os.open(IPC_FIFO_NAME_B, os.O_WRONLY)
                print("Pipe B ready")
                break
            except:
                # Wait until Pipe B has been initialized
                pass

        try:
            poll = select.poll()
            poll.register(fifo_a, select.POLLIN)

            try:
                while True:
                    if (fifo_a, select.POLLIN) in poll.poll(1000):  # Poll every 1 sec
                        msg = get_message(fifo_a)                   # Read from Pipe A
                        msg = process_msg(msg)                      # Process Message
                        os.write(fifo_b, msg)                       # Write to Pipe B

                        print('----- Received from JS -----')
                        print("    "   msg.decode("utf-8"))
            finally:
                poll.unregister(fifo_a)
        finally:
            os.close(fifo_a)
    finally:
        os.remove(IPC_FIFO_NAME_A)
        os.remove(IPC_FIFO_NAME_B)
 

Node.js: писать и читать:

Далее, давайте напишем простую Node.js программа, которая записывает данные в канал. Есть несколько пакетов, которые делают это: named-pipe, fifo-js. Тем не менее, node предлагает функции, которые позволяют удобно настраивать IPC с помощью каналов. Приведенный ниже сценарий записывает данные каждые 1 секунду в канал A (отправка данных) и считывает из канала B (получение обработанных данных из Python). Для простоты данные здесь представляют собой текущее время в виде строки.

 const fs              = require('fs');
const { spawn, fork } = require('child_process');

const path_a = 'pipe_a';
const path_b = 'pipe_b';
let fifo_b   = spawn('mkfifo', [path_b]);  // Create Pipe B

fifo_b.on('exit', function(status) {
    console.log('Created Pipe B');

    const fd   = fs.openSync(path_b, 'r ');
    let fifoRs = fs.createReadStream(null, { fd });
    let fifoWs = fs.createWriteStream(path_a);

    console.log('Ready to write')

    setInterval(() => {
        console.log('-----   Send packet   -----');
        fifoWs.write(`${new Date().toISOString()}`);
    }, 1000);  // Write data at 1 second interval

    fifoRs.on('data', data => {

        now_time  = new Date();
        sent_time = new Date(data.toString());
        latency   = (now_time - sent_time);

        console.log('----- Received packet -----');
        console.log('    Date   : '   data.toString());
        console.log('    Latency: '   latency.toString()   ' ms');
    });
});

 

Примечание: Этот контент взят отсюда, вы можете проверить его для получения более подробной информации.

Комментарии:

1.Спасибо вам за ваше решение. Но я нашел эту библиотеку под названием PyNode github.com/fridgerator/PyNode, это решило мою проблему с чарммом.