Nodejs与Python进行双向通信过程是什么
Admin 2022-07-18 群英技术资讯 1035 次浏览
今天这篇我们来学习和了解“Nodejs与Python进行双向通信过程是什么”,下文的讲解详细,步骤过程清晰,对大家进一步学习和理解“Nodejs与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 输出。上述方式也是官方文档中的示例,目前该示例存在两个问题:
保证一次数据加载,多次使用的前提是 Python 进程启动后不能退出。Python 进程之所以退出是因为无事可做,所以常见的手段有循环,sleep,监听端口,这些手段可以翻译成同步阻塞任务,同步非阻塞任务,其中代价最小的就是同步非阻塞任务,然后可以想到 Linux 的 select,epoll,简单搜索了下 Python 的 epoll,好像还有原生的包。
index.py - 通过 epoll 监听 stdin
import sys
import fcntl
import select
from mb import MB
import json
mbe = 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 的双向通信,然后由于上述种种问题,在这里并不推荐使用这种方式,通过 HTTP 或 Socket 方式比这个香多了。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了js 标签语法使用,在 JavaScript 中提供了标签语句,用于标记指定的代码块,便于跳转到指定的位置。本文来记录一下标签语句的使用方法,需要的朋友可以参考一下
这篇文章主要介绍了Vue.js中NaiveUI组件文字渐变的实现,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
vue的防抖和节流是什么意思?一些朋友可能对防抖和节流不是很了解,对此这篇文章就给大家具体的介绍一下什么是防抖和节流,感兴趣的朋友接下来跟随小编一起学习一下吧。
用jQuery怎样验证输入是不是数字?在登录注册页面,我们通常需要对输入验证,那么我们怎样知道输入的是不是数字呢?下文给大家分享一个简单的验证数字示例,有一定参考价值,需要的朋友可以参考看看。
可避免关闭窗口,程序就关闭,可在后台运行安装forever包,一般用于服务器,调试环境可不安装npminstallforever-g启动方式如图: 查询后台运行哪些程序foreverlist
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 ICP核准(ICP备案)粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008