使用 N-API 将数据流式传输到 Node.js C++ 插件
Streaming data into a Node.js C++ Addon with N-API
我正在为 NodeJS 构建一个 C++ 插件,我想将数据从 C++ 异步流式传输到 Node。然而,我找到了这篇文章,https://nodeaddons.com/streaming-data-into-a-node-js-c-addon/;我想使用 N-API 而不是 NAN。
我一直在搜索 NodeJS 文档和示例,并寻找其他资源和示例,但没有找到可以告诉我如何完成此操作的资源。这是我第一次为 NodeJS 编写 C++ 插件。
一个可以帮助我入门的示例是一个插件,它使用 N-API 每秒向 Node 发送一个虚拟字符串,Node 会将字符串打印到控制台。
这是一个基于 EventEmitter 概念的片段,它模拟从本机层 (C/C++) 读取传感器并将数据推送到 Node.js (JavaScript) 层。在这个例子中,我们使用 node-addon-api,header-only 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 )
编译上面的本机代码,一旦成功构建,您就可以运行下面的node.jsJavaScript代码来测试它。
'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
我正在为 NodeJS 构建一个 C++ 插件,我想将数据从 C++ 异步流式传输到 Node。然而,我找到了这篇文章,https://nodeaddons.com/streaming-data-into-a-node-js-c-addon/;我想使用 N-API 而不是 NAN。
我一直在搜索 NodeJS 文档和示例,并寻找其他资源和示例,但没有找到可以告诉我如何完成此操作的资源。这是我第一次为 NodeJS 编写 C++ 插件。
一个可以帮助我入门的示例是一个插件,它使用 N-API 每秒向 Node 发送一个虚拟字符串,Node 会将字符串打印到控制台。
这是一个基于 EventEmitter 概念的片段,它模拟从本机层 (C/C++) 读取传感器并将数据推送到 Node.js (JavaScript) 层。在这个例子中,我们使用 node-addon-api,header-only 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 )
编译上面的本机代码,一旦成功构建,您就可以运行下面的node.jsJavaScript代码来测试它。
'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