2017-05-25 11 views
2

私はネイティブCライブラリを呼び出すノードjsサービスを持っています。ネイティブライブラリは、繰り返し、連続的にイベントを発生させます。これらのイベントは、Cのコールバック関数に渡されます。私の目標は、このネイティブCコールバックからJavascriptコールバックを呼び出すことです。nodejs addon libuvでの非同期コールバック

私の読書に基づいて、私はこの目標を達成するためにuv_async_initとuv_async_sendを使用しています。

私が遭遇している問題は、ネイティブのCコールバック関数が何度も呼び出され、そこにuv_async_sendが何度も呼び出されるということですが、uv_async_initに渡される関数は、プログラムが終了するときにのみ一度だけ呼び出されます。ここで

は私のCコードです:

==================================== =================

#include "jsaudio.h" 
#include <iostream> 

using namespace v8; 

static void recordAudioCallback(int index); 
void asyncmsg(uv_async_t* handle); 
Callback* cbPeriodic; 
uv_async_t async; 
uv_loop_t* loop; 

NAN_METHOD(createEngine) { 
    std::cout << "==> createEngine\n" ; 
} 

void createAudioRecorder(const Nan::FunctionCallbackInfo<v8::Value>& info) { 
    std::cout << "==> createAudioRecorder\n"; 
} 

void startRecording(const Nan::FunctionCallbackInfo<v8::Value>& info) { 
    std::cout << "==> startRecording\n"; 
    cbPeriodic = new Callback(info[0].As<Function>()); 
    loop = uv_default_loop(); 
    uv_async_init(loop, &async, asyncmsg); 
} 

void asyncmsg(uv_async_t* handle) { 
    std::cout << "==> asyncmsg \n"; 
    Nan::HandleScope scope; 
    v8::Isolate* isolate = v8::Isolate::GetCurrent(); 
    Local<Value> argv[] = { v8::String::NewFromUtf8(isolate, "Hello world") }; 
    cbPeriodic->Call(1, argv); 
} 

/* This my callback that gets called many times, by a native library*/ 
static void recordAudioCallback(int index) { 
    std::cout << "==> recordAudioCallback " << index << "\n"; 
    uv_async_send(&async); 
} 

========================== ============================ここ

は、上記ネイティブコード

const jsAudio = new JsAudio({sampleRate: 48000, bufferSize: 8192}) 

function Test() { 
    jsAudio.createEngine(); 

    jsAudio.createAudioRecorder(); 

    jsAudio.startRecording(function(error, result) { 
    if (error) { 
     console.log('startRecording failed: ' + error); 
    } else { 
     console.log('startRecording result: ' + result); 
    } 
    }); 
} 

Test(); 

var waitTill = new Date(new Date().getTime() + 3 * 1000); 
while(waitTill > new Date()){} 

jsAudio.shutdown(); 

console.log('program exit...'); 
を呼び出し、私のテストのNode.jsのコードです

============ ===========================

ここに出ては、次のとおりです。

==> createEngine 
==> createAudioRecorder 
==> startRecording 
==> recordAudioCallback 0 
==> recordAudioCallback 1 
==> recordAudioCallback 0 
==> recordAudioCallback 1 
==> recordAudioCallback 0 
==> shutdown 
program exit... 
==> asyncmsg 
startRecording failed: Hello world 

====================================== =====================

なぜasyncmsgが一度だけ呼び出されるのですか?たとえrecordAudioCallbackが何度も呼び出されたとしても!プログラム終了後に呼び出される理由は何ですか?

何か助けていただければ幸いです。

+0

(AFAIK)Node.jsアドオンはCではなく、Cで書かれているだけなので、特にC言語ではありません。これらは完全に別の言語であり、助けを得る確率を最大限に高めるには、 C++コード "C"を呼び出すことはできません。 – Frxstrem

答えて

2

node.jsのJavascriptコードの実際の実行はシングルスレッドです。つまり、既に実行中のJSコードの途中でコールバックを実行することはできません。

サンプルコードには、一定時間連続して実行されるビジーループが含まれている場合、プログラムは終了します。ループが実行されている間にコールバックが実行される機会はありません。

setTimeoutの呼び出しで置き換えて、必要な間隔でタイムアウトを設定してください。

const jsAudio = new JsAudio({sampleRate: 48000, bufferSize: 8192}) 

function Test() { 
    jsAudio.createEngine(); 

    jsAudio.createAudioRecorder(); 

    jsAudio.startRecording(function(error, result) { 
    if (error) { 
     console.log('startRecording failed: ' + error); 
    } else { 
     console.log('startRecording result: ' + result); 
    } 
    }); 
} 

Test(); 

setTimeout(function() { 
    jsAudio.shutdown(); 
    console.log('program exit...'); 
}, 3000); 

setTimeoutの呼び出しがすぐに戻るにもかかわらず、プログラムは終了しないことに注意してください。これは、node.jsには、保留中のタイマーや処理待ちの他のイベントがある限り継続するイベントループがあるためです。

イベントループの説明については、node.jsのドキュメントのthis sectionを参照してください。

+0

ありがとうございます。それは私の問題を解決しました。 –

+0

@ S.Vagharへようこそスタックオーバーフロー。回答が問題を解決した場合は、(左のチェックマークをクリックして)それを受け入れたものとしてマーキングしてください、そして/またはupvotingしてください。それは他の人がここで役に立つ答えを見つけるのを助ける。 – harmic

関連する問題