最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node與Python 雙向通信的實(shí)現(xiàn)代碼

 更新時(shí)間:2021年07月16日 15:53:53   作者:SUNTOPO  
最簡單粗暴的通信方式是 Nodejs調(diào)用一下 Python 腳本,本文詳細(xì)介紹了Nodejs與Python 雙向通信的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

第三方數(shù)據(jù)供應(yīng)商把數(shù)據(jù)和Python封裝到一起,只能通過調(diào)用 Python方法來實(shí)現(xiàn)數(shù)據(jù)查詢,如果可以通過Node 簡單封裝下實(shí)現(xiàn) Python 方法調(diào)用可以快速上線并節(jié)省開發(fā)成本。

最簡單粗暴的通信方式是 Nodejs調(diào)用一下 Python 腳本,然后獲取子進(jìn)程的輸出,但是由于每次 Python 啟動(dòng)并加載數(shù)據(jù)包的過程比較漫長,所以對(duì)該過程優(yōu)化。

進(jìn)程通信

index.py

# 封裝的 Python 包, 體積巨大
from mb import MB
# 從數(shù)據(jù)包中查詢
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 子進(jìn)程,監(jiān)聽 stdout 輸出。上述方式也是官方文檔中的示例,目前該示例存在兩個(gè)問題:

  • Nodejs 沒有向 Python 發(fā)送數(shù)據(jù)
  • Nodejs 調(diào)用完畢后,Python 子進(jìn)程會(huì)退出;下次查詢需要再次調(diào)用Python命令進(jìn)行加載文件,查詢數(shù)據(jù);無法實(shí)現(xiàn)一次內(nèi)存加載,多次使用。

進(jìn)程雙向通信

保證一次數(shù)據(jù)加載,多次使用的前提是 Python 進(jìn)程啟動(dòng)后不能退出。Python 進(jìn)程之所以退出是因?yàn)闊o事可做,所以常見的手段有循環(huán),sleep,監(jiān)聽端口,這些手段可以翻譯成同步阻塞任務(wù),同步非阻塞任務(wù),其中代價(jià)最小的就是同步非阻塞任務(wù),然后可以想到 Linux 的 select,epoll,簡單搜索了下 Python 的 epoll,好像還有原生的包。

index.py - 通過 epoll 監(jiān)聽 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() # 通過標(biāo)準(zhǔn)輸入獲取數(shù)據(jù)
            if data == '' or data == '\n':
                continue
            items = xxx # 數(shù)處理過程
            for item in items:
                result = mbe.get(item)
                sys.stdout.write(json.dumps(result, ensure_ascii=False) +'\n') # 寫入到標(biāo)準(zhǔn)輸出
                sys.stdout.flush() # 緩沖區(qū)刷新
finally:
    epoll.unregister(fd)
    epoll.close()

index.js - 通過 stdin 發(fā)送數(shù)據(jù)

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 無法動(dòng)態(tài)擴(kuò)容
    
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 結(jié)尾
                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端的標(biāo)準(zhǔn)輸入輸出沒有flush方法,只能 hack, 寫入后python無法及時(shí)獲取到最新
}, 500)

exports.getMsg = function getMsg(ip, cb) {
    callbacks.push(cb)
    child.stdin.write(`${ip}\n`); // 把數(shù)據(jù)寫入到子進(jìn)程的標(biāo)準(zhǔn)輸入
}

Python 與 Nodejs 通過 stdio 實(shí)現(xiàn)通信; Python 通過 epoll 監(jiān)聽 stdin 實(shí)現(xiàn)駐留內(nèi)存,長時(shí)間運(yùn)行。

存在問題

  • Nodejs 把標(biāo)準(zhǔn)輸出作為執(zhí)行結(jié)果,故 Python 端只能把執(zhí)行結(jié)果寫入標(biāo)準(zhǔn)輸出,不能有額外的打印信息
  • Nodejs 端標(biāo)準(zhǔn)輸入沒有 flush 方法,所以 Python 端事件觸發(fā)不夠及時(shí),目前通過在Nodejs端定時(shí)發(fā)送空信息來 hack 實(shí)現(xiàn)
  • Buffer 沒法動(dòng)態(tài)擴(kuò)容,沒有C語言的指針好用,在解析 stdout 時(shí)寫丑

總結(jié)

雖然可以實(shí)現(xiàn) Nodejs 和 Python 的雙向通信,然后由于上述種種問題,在這里并不推薦使用這種方式,通過 HTTP 或 Socket 方式比這個(gè)香多了。

到此這篇關(guān)于Nodejs與Python 雙向通信的實(shí)現(xiàn)代碼的文章就介紹到這了,更多相關(guān)Nodejs與Python雙向通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用Nodejs編寫一個(gè)腳本實(shí)現(xiàn)markdown轉(zhuǎn)pdf功能

    使用Nodejs編寫一個(gè)腳本實(shí)現(xiàn)markdown轉(zhuǎn)pdf功能

    Markdown?是一種輕量級(jí)的標(biāo)記語言,非常適合用來寫作和記錄,將?Markdown?轉(zhuǎn)換為?PDF?可以讓文檔在格式和樣式上更加統(tǒng)一,也方便在不同設(shè)備和平臺(tái)上查看和打印,在接下來的內(nèi)容中我們將講解如何使用?NodeJs?編寫一個(gè)?Markdown?轉(zhuǎn)?PDF?的腳本來實(shí)現(xiàn)我們這個(gè)想要的功能
    2024-05-05
  • node.js中的url.format方法使用說明

    node.js中的url.format方法使用說明

    這篇文章主要介紹了node.js中的url.format方法使用說明,本文介紹了url.format的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node.js使用MySQL連接池的方法實(shí)例

    Node.js使用MySQL連接池的方法實(shí)例

    這篇文章主要介紹了Node.js使用MySQL連接池的方法,結(jié)合具體實(shí)例形式分析了nodejs操作mysql連接池的相關(guān)模塊安裝、連接、查詢等使用技巧,需要的朋友可以參考下
    2018-02-02
  • Node.js模擬發(fā)起http請(qǐng)求從異步轉(zhuǎn)同步的5種用法

    Node.js模擬發(fā)起http請(qǐng)求從異步轉(zhuǎn)同步的5種用法

    這篇文章主要介紹了Node.js模擬發(fā)起http請(qǐng)求從異步轉(zhuǎn)同步的5種方法,下面總結(jié)了幾個(gè)常見的庫 API 從異步轉(zhuǎn)同步的幾種方法。需要的朋友可以參考下
    2018-09-09
  • nodejs基礎(chǔ)之buffer緩沖區(qū)用法分析

    nodejs基礎(chǔ)之buffer緩沖區(qū)用法分析

    這篇文章主要介紹了nodejs基礎(chǔ)之buffer緩沖區(qū)用法,結(jié)合實(shí)例形式分析了buffer緩沖區(qū)的概念、功能、創(chuàng)建、讀寫等相關(guān)操作技巧,需要的朋友可以參考下
    2018-12-12
  • nodejs之get/post請(qǐng)求的幾種方式小結(jié)

    nodejs之get/post請(qǐng)求的幾種方式小結(jié)

    下面小編就為大家?guī)硪黄猲odejs之get/post請(qǐng)求的幾種方式小結(jié)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • nodejs版本過高導(dǎo)致vue-cli項(xiàng)目無法正常運(yùn)行的幾種解決方案

    nodejs版本過高導(dǎo)致vue-cli項(xiàng)目無法正常運(yùn)行的幾種解決方案

    這篇文章主要給大家介紹了關(guān)于nodejs版本過高導(dǎo)致vue-cli項(xiàng)目無法正常運(yùn)行的幾種解決方案,在項(xiàng)目中你可能需要用到的node版本太低,但是你所下的node版本是最新的,這時(shí)候就會(huì)報(bào)錯(cuò),需要的朋友可以參考下
    2023-07-07
  • 詳解nodejs實(shí)現(xiàn)本地上傳圖片并預(yù)覽功能(express4.0+)

    詳解nodejs實(shí)現(xiàn)本地上傳圖片并預(yù)覽功能(express4.0+)

    本篇文章主要介紹了nodejs實(shí)現(xiàn)本地上傳圖片并預(yù)覽功能(express4.0+) ,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-06-06
  • 詳解NodeJS模塊化

    詳解NodeJS模塊化

    簡單的說Node.js就是運(yùn)行在服務(wù)端的JavaScript。Node.js是一個(gè)基于Chrome JavaScript運(yùn)行時(shí)建立的一個(gè)平臺(tái)。Node.js是一個(gè)事件驅(qū)動(dòng)I/O服務(wù)端JavaScript環(huán)境,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非???,性能非常好
    2021-06-06
  • Node.js在child_process域和錯(cuò)誤冒泡及捕獲實(shí)踐

    Node.js在child_process域和錯(cuò)誤冒泡及捕獲實(shí)踐

    這篇文章主要為大家介紹了Node.js在child_process域和錯(cuò)誤冒泡及捕獲實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評(píng)論

白玉县| 郯城县| 岳阳县| 大石桥市| 南丰县| 宜兰县| 阜康市| 包头市| 佛冈县| 平邑县| 天长市| 临漳县| 蓬莱市| 时尚| 贵定县| 耒阳市| 鸡东县| 乌兰县| 积石山| 蕲春县| 乳源| 克东县| 马公市| 微山县| 合川市| 昌都县| 通化县| 洪洞县| 莆田市| 南丰县| 盐亭县| 商丘市| 乡城县| 横山县| 和顺县| 井陉县| 汾西县| 侯马市| 伊宁市| 鹤山市| 安化县|