Потоковая передача данных в аддон Node.js C ++ с N-API - PullRequest
2 голосов
/ 11 апреля 2019

Я создаю аддон C ++ для NodeJS и хочу асинхронно передавать данные из C ++ в Node. Я нашел эту статью, однако https://nodeaddons.com/streaming-data-into-a-node-js-c-addon/,; Я хочу использовать N-API вместо NAN.

Я искал документы и примеры NodeJS, а также искал другие ресурсы и примеры, но не нашел ресурса, чтобы показать мне, как я могу это сделать. Я впервые пишу аддон C ++ для NodeJS.

Примером, который может помочь мне начать работу, является дополнение, которое использует N-API для отправки фиктивной строки каждую секунду в Node, а Node будет печатать строку в консоли.

1 Ответ

2 голосов
/ 12 апреля 2019

Вот фрагмент, основанный на концепции EventEmitter, которая имитирует считывание датчиков с нативного уровня (C / C ++) и передает данные на уровень Node.js (JavaScript). В этом примере мы используем node-addon-api, оболочку C ++ только для заголовка для N-API . Здесь для этого примера мы использовали цикл 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" );
}

Фрагмент регистрации модуля -

#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 )

Скомпилируйте вышеприведенный собственный код, и после его успешной сборки вы можете запустить следующий код JavaScript node.js для его проверки.

'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();

Фрагмент кода должен выдать следующий вывод.

### 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
...