如何将带有可读流的数据从 NodeJS 发送到 C++

how to send data with Readable stream from NodeJS to C++

我目前正在从 C++ 向 NodeJS 发送数据,将 NodeJS readableStream.push.bind(readableStream) 传递给 C++ 绑定代码,并使用

从 C++ 写入流
Napi::Function push = info[0].As<Napi::Function>();
Napi::ThreadSafeFunction push_safe = Napi::ThreadSafeFunction::New(env, push, "push", 0, 1);
push_safe.BlockingCall(data, custom_callback);

现在我希望能够使用 NodeJS Stream 将数据发送到 C++ 绑定,但我无法确定 C++ 是否可以接受 Stream,并调用 .on('data', (data) => {}) 的 C++ 版本它,类似于:

NodeJS 示例:

const read_stream = fs.createReadStream("./random.bin");
mybinding.myfunc(read_stream);

示例 C++:

Value myfunc(const CallbackInfo& info) {
  Env env = info.Env();

  auto on_data_lambda = [](data)
  {
    std::cout << "new data arrived from nodejs stream: " << data << std::endl;
  }

  /*some magic*/
}


用所有的花里胡哨来实现这一点并非易事。一如既往,最复杂的部分是处理所有错误。

我建议您查看 Node.js 来源 src/js_stream.cc,其中包含类似的内容,您将理解为什么 good/fast 实施很困难。

如果您想保持简单,可以先创建一个对 C++ on_data 函数的 JS 引用。

然后你就可以把这个函数注册为事件接收器了。

Napi::Value ondata(const Napi::CallbackInfo &info) {
  if (!info[0].IsObject()) printf("Something strange received");
  else printf("received %s\n", info[0].ToString().Utf8Value().c_str());
  return info.Env().Undefined();
}

Napi::Value stream(const Napi::CallbackInfo &info) {
  Napi::Object stream = info[0].ToObject();
  Napi::Function on_data_ref = Napi::Function::New(info.Env(), ondata, "on_data");
  Napi::Value onValue = stream.Get("on");
  if (!onValue.IsFunction()) throw Napi::Error::New(info.Env(), "This is not an event emitter");
  Napi::Function on = onValue.As<Napi::Function>();
  on.Call(stream, {Napi::String::New(info.Env(), "data"), on_data_ref});
  return info.Env().Undefined();
}

如果您这样做,数据将开始流动。但是你仍然必须正确地做错误处理和其他一切。