iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Node与Python双向通信的实现方法
  • 349
分享到

Node与Python双向通信的实现方法

2023-06-20 16:06:07 349人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章主要介绍“node与python双向通信的实现方法”,在日常操作中,相信很多人在Node与Python双向通信的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node与Python双向通信的实

这篇文章主要介绍“nodepython双向通信的实现方法”,在日常操作中,相信很多人在Node与Python双向通信的实现方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node与Python双向通信的实现方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

目录
  • 进程通信

  • 进程双向通信

  • 存在问题

  • 总结

第三方数据供应商把数据和Python封装到一起,只能通过调用 Python方法来实现数据查询,如果可以通过Node 简单封装下实现 Python 方法调用可以快速上线并节省开发成本。

最简单粗暴的通信方式是 nodejs调用一下 Python 脚本,然后获取子进程的输出,但是由于每次 Python 启动并加载数据包的过程比较漫长,所以对该过程优化

进程通信

index.py

# 封装的 Python 包, 体积巨大from mb import MB# 从数据包中查询mbe.get('1.0.1.0')

index.js

const { spawn } = require('child_process');const ls = spawn('python3', ['index.py']);ls.stdout.on('data', (data) => {  console.log(`stdout: ${data}`);});ls.stderr.on('data', (data) => {  console.error(`stderr: ${data}`);});ls.on('close', (code) => {  console.log(`child process exited with code $[code]`);});

通过child_process.spawn来派生 Python 子进程,监听 stdout 输出。上述方式也是官方文档中的示例,目前该示例存在两个问题:

  • Nodejs 没有向 Python 发送数据

  • Nodejs 调用完毕后,Python 子进程会退出;下次查询需要再次调用Python命令进行加载文件,查询数据;无法实现一次内存加载,多次使用。

进程双向通信

保证一次数据加载,多次使用的前提是 Python 进程启动后不能退出。Python 进程之所以退出是因为无事可做,所以常见的手段有循环,sleep,监听端口,这些手段可以翻译成同步阻塞任务,同步非阻塞任务,其中代价最小的就是同步非阻塞任务,然后可以想到 linux 的 select,epoll,简单搜索了下 Python 的 epoll,好像还有原生的包。

index.py - 通过 epoll 监听 stdin

import sysimport fcntlimport selectfrom mb import MBimport JSONmbe = MB('./data')# epoll 模型fd = sys.stdin.fileno()epoll = select.epoll()epoll.reGISter(fd, select.EPOLLIN)try:    while True:        events = epoll.poll(10) # 同步非阻塞        data = ''        for fileno, event in events:            data += sys.stdin.readline() # 通过标准输入获取数据            if data == '' or data == '\n':                continue            items = xxx # 数处理过程            for item in items:                result = mbe.get(item)                sys.stdout.write(json.dumps(result, ensure_ascii=False) +'\n') # 写入到标准输出                sys.stdout.flush() # 缓冲区刷新finally:    epoll.unregister(fd)    epoll.close()

index.js - 通过 stdin 发送数据

const child_process = require('child_process');const child = child_process.spawn('python3', ['./base.py']);let callbacks =  [],     chunks=Buffer.alloc(0),     chunkArr = [],     data = '',     onwork = false; // buffer 无法动态扩容    child.stdout.on('data', (chunk) => {    chunkArr.push(chunk)    if (onwork) return;    onwork = true;    while(chunkArr.length) {        chunks = Buffer.concat([chunks, chunkArr.pop()]);        const length = chunks.length;        let trunkAt = -1;        for(const [k, d] of chunks.entries()) {            if (d == '0x0a') { // 0a 结尾                data += chunks.slice(trunkAt+1, trunkAt=k);                const cb = callbacks.shift();                cb(null, data === 'null' ? null : data )                data = '';            }        }        if (trunkAt < length) {            chunks = chunks.slice(trunkAt+1)        }    }    onwork = false;})setInterval(() => {    if (callbacks.length) child.stdin.write(`\n`); // Nodejs端的标准输入输出没有flush方法,只能 hack, 写入后python无法及时获取到最新}, 500)exports.getMsg = function getMsg(ip, cb) {    callbacks.push(cb)    child.stdin.write(`${ip}\n`); // 把数据写入到子进程的标准输入}

Python 与 Nodejs 通过 stdio 实现通信; Python 通过 epoll 监听 stdin 实现驻留内存,长时间运行。

存在问题

  • Nodejs 把标准输出作为执行结果,故 Python 端只能把执行结果写入标准输出,不能有额外的打印信息

  • Nodejs 端标准输入没有 flush 方法,所以 Python 端事件触发不够及时,目前通过在Nodejs端定时发送空信息来 hack 实现

  • Buffer 没法动态扩容,没有C语言的指针好用,在解析 stdout 时写丑

总结

虽然可以实现 Nodejs 和 Python 的双向通信,然后由于上述种种问题,在这里并不推荐使用这种方式,通过 HttpSocket 方式比这个香多了。

到此,关于“Node与Python双向通信的实现方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Node与Python双向通信的实现方法

本文链接: https://www.lsjlt.com/news/298232.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作