【问题标题】:Streaming data into a Node.js C++ Addon with N-API使用 N-API 将数据流式传输到 Node.js C++ 插件
【发布时间】:2019-04-11 17:03:24
【问题描述】:

我正在为 NodeJS 构建一个 C++ 插件,我想将数据从 C++ 异步流式传输到 Node.js。但是,我找到了这篇文章,https://nodeaddons.com/streaming-data-into-a-node-js-c-addon/;我想使用 N-API 而不是 NAN。

我一直在搜索 NodeJS 文档和示例以及寻找其他资源和示例,但还没有找到资源来告诉我如何实现这一点。这是我第一次为 NodeJS 编写 C++ 插件。

一个可以帮助我入门的示例是一个插件,它使用 N-API 每秒向 Node 发送一个虚拟字符串,Node 会将字符串打印到控制台。

【问题讨论】:

    标签: c++ node.js node.js-addon node-addon-api n-api


    【解决方案1】:

    这是一个基于 EventEmitter 概念的 sn-p,它模拟从原生层(C/C++)读取传感器并将数据推送到 Node.js(JavaScript)层。在这个例子中,我们使用了 node-addon-api,一个只有头文件的 N-API 的 C++ 包装器。在此示例中,我们使用了一个 for 循环(只有五个迭代),实际上它可能是一个无限循环,不断读取传感器输出并将数据推送到 JS 层。本机层可以决定何时将其从传感器收集的数据报告给 JS 层。 JS 将异步接收订阅事件的数据。

    #include <napi.h>
    #include <thread>
    
    Napi::Value CallEmit(const Napi::CallbackInfo &info)
    {
        char buff1[128];
        char buff2[128];
        int  sensor1 = 0;
        int  sensor2 = 0;
    
        Napi::Env env = info.Env();
    
        Napi::Function emit = info[0].As<Napi::Function>();
        emit.Call(  {Napi::String::New(env, "start")}  );
    
        for (int i = 0; i < 5; i++)
        {
            // Let us simulate some delay for collecting data from its sensors
            std::this_thread::sleep_for(std::chrono::seconds(2));
    
            sprintf(buff1, "sensor1 data %d ...", ++sensor1);
    
            emit.Call( { Napi::String::New(env, "sensor1"),
                       Napi::String::New(env, buff1 ) } );
    
            // Let, sensor 2 data is reported half the rate as sensor1
            if (i % 2)
            {
                sprintf(buff2, "sensor2 data %d ...", ++sensor2);
                emit.Call({ Napi::String::New(env, "sensor2"),
                           Napi::String::New(env, buff2) });
            }
        }
    
        emit.Call( {Napi::String::New(env, "end")} );
        return Napi::String::New( env, "OK" );
    }
    

    模块注册sn-p为

    #include <napi.h>
    
    Napi::Object Init( Napi::Env env, Napi::Object exports )
    {
      exports.Set(Napi::String::New(env, "callEmit"), Napi::Function::New(env, CallEmit));
      return exports;
    }
    
    NODE_API_MODULE( myncpp1, Init )
    

    编译上面的原生代码,一旦编译成功,你就可以运行下面的node.js JavaScript 代码来测试它。

    'use strict'
    
    const EventEmitter = require('events').EventEmitter
    const addon = require('bindings')('myncpp1')
    
    // General theme of EventEmitter is: notify me when it is ready
    
    function Main() {
        const emitter = new EventEmitter()
    
        emitter.on('start', () => {
            console.log( '### Sensor reading started ...');
        })
    
        emitter.on('sensor1', (evt) => {
            // This module will be called as on when the
            // sensor1 data available for consuming from JS
            console.log(evt);
        })
    
        emitter.on('sensor2', (evt) => {
            console.log(evt);
        })
    
        emitter.on('end', () => {
            console.log('### Sensor reading Ended');
        })
    
        addon.callEmit( emitter.emit.bind(emitter) )
    }
    
    Main();
    

    代码 sn-p 应该产生以下输出。

    ### Sensor reading started ...
    sensor1 data 1 ...
    sensor1 data 2 ...
    sensor2 data 1 ...
    sensor1 data 3 ...
    sensor1 data 4 ...
    sensor2 data 2 ...
    sensor1 data 5 ...
    ### Sensor reading Ended
    

    【讨论】:

    • 效果很好,谢谢!是否可以从另一个线程进行发射器回调?我认为这需要一个新问题。 stackoverflow.com/questions/55714406/…
    • 谢谢。我将在不久的将来使用它,并感谢您花时间提供代码。也许我们可以在这里得到一个活跃的 node-addon-api 标签!
    猜你喜欢
    • 1970-01-01
    • 2011-02-03
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多