【问题标题】:How to communicate between node.js process and a python process如何在 node.js 进程和 python 进程之间进行通信
【发布时间】:2021-06-13 06:53:19
【问题描述】:

我有一个 node.js 进程和一个 python 进程并行运行。 Node.js 进程是一个 http 服务器。每当我收到请求时,我想在 python 进程中调用可调用对象(函数/或任何可调用对象)并从 node.js 代码传递一些环境变量和可调用函数。在伪代码中类似于

// 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"

这两个进程之间的通信方式是什么。我可以使用childprocess 从node.js 生成一个python 进程,但是如何将javascript 函数传递给python?如何解决这个问题?提前致谢。

【问题讨论】:

    标签: python node.js unix process wsgi


    【解决方案1】:

    您可以使用Named Pipes。目标是使用命名管道进行通信。

    1. Node.js 进程会将一些数据写入管道 (A)
    2. Python 进程从管道 (A) 读取数据并操作数据
    3. 上面的python进程然后将数据写入管道(B)
    4. Node.js 从管道 (B) 读取

    Python:读取、处理和写入

    首先,让我们创建一个简单的 Python 进程,它从命名管道 A 读取数据,处理数据,然后将其写入命名管道 B(为简单起见,此处的 process_msg() 函数返回读取的数据)。该脚本首先使用 os.mkfifo() 命令创建命名管道 A。

    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-pipefifo-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');
        });
    });
    
    

    注意:此内容取自here,您可以查看更多详细信息。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    • 2018-09-16
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    相关资源
    最近更新 更多