Node与Python双向通信如何实现
Node与Python双向通信如何实现
这篇文章主要介绍“Node与Python双向通信如何实现”,在日常操作中,相信很多人在Node与Python双向通信如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node与Python双向通信如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
第三方数据供应商把数据和Python封装到一起,只能通过调用 Python方法来实现数据查询,如果可以通过Node 简单封装下实现 Python 方法调用可以快速上线并节省开发成本。
最简单粗暴的通信方式是 Nodejs调用一下 Python 脚本,然后获取子进程的输出,但是由于每次 Python 启动并加载数据包的过程比较漫长,所以对该过程优化。
进程通信
index.py
#封装的Python包,体积巨大frommbimportMB#从数据包中查询mbe.get("1.0.1.0")
index.js
const{spawn}=require("child_process");constls=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(`childprocessexitedwithcode$[code]`);});
通过child_process.spawn来派生 Python 子进程,监听 stdout 输出。上述方式也是官方文档中的示例,目前该示例存在两个问题:
Nodejs 没有向 Python 发送数据
Nodejs 调用完毕后,Python 子进程会退出;下次查询需要再次调用Python命令进行加载文件,查询数据;无法实现一次内存加载,多次使用。
进程双向通信
保证一次数据加载,多次使用的前提是 Python 进程启动后不能退出。Python 进程之所以退出是因为无事可做,所以常见的手段有循环,sleep,监听端口,这些手段可以翻译成同步阻塞任务,同步非阻塞任务,其中代价最小的就是同步非阻塞任务,然后可以想到 Linux 的 select,epoll,简单搜索了下 Python 的 epoll,好像还有原生的包。
index.py - 通过 epoll 监听 stdin
importsysimportfcntlimportselectfrommbimportMBimportjsonmbe=MB("./data")#epoll模型fd=sys.stdin.fileno()epoll=select.epoll()epoll.register(fd,select.EPOLLIN)try:whileTrue:events=epoll.poll(10)#同步非阻塞data=""forfileno,eventinevents:data+=sys.stdin.readline()#通过标准输入获取数据ifdata==""ordata=="":continueitems=xxx#数处理过程foriteminitems:result=mbe.get(item)sys.stdout.write(json.dumps(result,ensure_ascii=False)+"")#写入到标准输出sys.stdout.flush()#缓冲区刷新finally:epoll.unregister(fd)epoll.close()
index.js - 通过 stdin 发送数据
constchild_process=require("child_process");constchild=child_process.spawn("python3",["./base.py"]);letcallbacks=[],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()]);constlength=chunks.length;lettrunkAt=-1;for(const[k,d]ofchunks.entries()){if(d=="0x0a"){//0a结尾data+=chunks.slice(trunkAt+1,trunkAt=k);constcb=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(``);//Nodejs端的标准输入输出没有flush方法,只能hack,写入后python无法及时获取到最新},500)exports.getMsg=functiongetMsg(ip,cb){callbacks.push(cb)child.stdin.write(`${ip}`);//把数据写入到子进程的标准输入}
Python 与 Nodejs 通过 stdio 实现通信; Python 通过 epoll 监听 stdin 实现驻留内存,长时间运行。
存在问题
Nodejs 把标准输出作为执行结果,故 Python 端只能把执行结果写入标准输出,不能有额外的打印信息
Nodejs 端标准输入没有 flush 方法,所以 Python 端事件触发不够及时,目前通过在Nodejs端定时发送空信息来 hack 实现
Buffer 没法动态扩容,没有C语言的指针好用,在解析 stdout 时写丑
到此,关于“Node与Python双向通信如何实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注恰卡编程网网站,小编会继续努力为大家带来更多实用的文章!
推荐阅读
-
node是不是免费的
node是不是免费的本文小编为大家详细介绍“node是不是免费的”...
-
Node中的可读流是什么
-
python多行注释符号怎么表示
python多行注释符号怎么表示这篇文章主要介绍“python多行...
-
怎么开发一个node切换源小工具
-
python支持的操作系统是什么
python支持的操作系统是什么这篇文章主要介绍“python支持...
-
Node http模块基本使用方法是什么
-
node消息队列怎么使用
-
Node中express的身份认证怎么使用
-
python如何判断列表为空
python如何判断列表为空这篇文章主要介绍“python如何判断...
-
Python如何利用D3Blocks绘制可动态交互的图表