2017-09-04 2 views
2

私はソケットのメッセージを処理するAsyncProgressWorkerスレッドを使用してノードのアドオンを作った。その後、私はいくつかのメッセージが戻っノードにそれをすることはありませんことに気づいいくつかprogress.Send呼び出しnodejs土地にしないでください

class ProgressWorker : public AsyncProgressWorker { 
public: 
    ProgressWorker(
     Callback *callback 
    , Callback *progress) 
    : AsyncProgressWorker(callback), progress(progress) {} 
    ~ProgressWorker() {} 

    void Execute (const AsyncProgressWorker::ExecutionProgress& progress) { 
    char response[4096]; 
    int result; 
    int connected = 1; 
    int timeout = 0; 
    int pending = 0; 

    while(connected) { 
     result = sctp_recvmsg(sock, (void *)&response, (size_t)sizeof(response), NULL, 0, 0, 0); 
     if (result > 0 && result < 4095) { 
      if (debug) { 
       printf("Server replied (size %d)\n", result); 
      } 
      pending = 0; 
      progress.Send((const char *)response, size_t(result)); 
      result = 0; 
     } 
     else { 
      // Don't mind my timeout mechanism. :)) 
      if ((result == -1 && errno != EWOULDBLOCK) || pending) { 
       if (timeout == 0) { 
        printf("Can't receive from other end. Waiting for 3 seconds. Error code: %d\n", errno); 
        pending = 1; 
       } 
       if (timeout >= 3000) { 
        connected = 0; 
        close(sock); 
       } 
       else { 
        timeout += 5; 
        usleep(5000); 
       } 
      } 
      else { 
       usleep(5000); 
      } 
     } 
    } 

    } 

    void HandleProgressCallback(const char *data, size_t count) { 
    HandleScope scope; 

    v8::Local<v8::Value> argv[] = { 
     CopyBuffer(const_cast<char*>(data), count).ToLocalChecked() 
    }; 
    progress->Call(1, argv); // This is the callback to nodejs 
    } 

private: 
    Callback *progress; 
}; 

は、今私は今夜までこのことを強調し、テストしていません。ここに私のコードです。私の "Server replied"デバッグログは出力されますが、デバッグログはログに記録されません。私はここに何かを逃していますか前もって感謝します。

+0

ACKを実装しないのはなぜですか?package.jsonは、 (ちょうどパケットが落ちる時を確かめるために) – EMX

+0

@EMX答えに申し訳ありませんが、私はACKについてよく分かりません。私が言うことができるのは、これがSCTPソケット実装であることだけです。私はsctp_recvmsg戻り値に頼っています。欠落しているメッセージがデバッグログを渡しましたが、進捗コールバックは呼び出されません。ありがとう。 – Phenelo

+0

':: v8 :: Isolate'へのポインタを' HandleScope'コンストラクタに渡すべきではありませんか? – VTT

答えて

2

AsyncProgressWorkerは、に基づいています。これにより、どのスレッドもメインスレッドを復帰させることができます。しかし、documentationで述べたように:

libuvはつまり、それまでではないすべての呼び出し は、コールバックの実行をもたらすだろう、)(uv_async_sendの呼び出しを合体します。たとえば、 uv_async_send()が呼び出される前に行が5回呼び出された場合、 が呼び出されると、コールバックは1回だけ呼び出されます。 uv_async_send()がコールバックが呼び出された後に再び が呼び出されると、それは再び呼び出されます。

^^これは、アプリケーションに負荷がかかっている間にイベントが発生しないことがあるためです。この行の上に質問に対する答えがあります。ので、私はAsyncProgressWorkerと同じように、ごとイベントを提供することを約束AsyncProgressWorkerに新しい選択肢を追加することに取り組んでいますが、使用していることが起こる

:以下は、あなたの問題に対処するために、私の「上とを超えて」可能な解決策でありますキュー。この機能は最近NANに統合されました。テストする場合は、https://github.com/nodejs/nanでgitリポジトリを試してから、AsyncProgressWorkerAsyncProgressQueueWorker<char>に置き換えてテストを再実行すると、すべてのイベントが配信されます。

この新機能を追加するためのプル要求はここにある:https://github.com/nodejs/nan/pull/692 - この新機能は、あなたがこの新しいを使用することができますNANバージョン2.8.0

にリリースされた10月6日、2017年

に合併

"dependencies": { 
    "nan": "^2.8.0" 
    }, 
+0

あなたの答えを遅く受け入れて申し訳ありませんが、私が解決策を探していたとき、私はここで私の質問について忘れました。とにかく、最近、私はそれがメッセージが通っていなかった理由であることを知った。実際には、メッセージのキューイングを自分で作成しています。しかし、私はこれを試してみます。ありがとう。 – Phenelo

+0

ありがとう、それは動作します!残りの問題は、メッセージの送信部分をキューに入れることです。しかしそれは別の話です。 – Phenelo

+0

テンプレートクラスの名前を 'AsyncWakeRequestor'から' AsyncProgressQueueWorker'に変更するオープンプルリクエストを変更しました。それに応じてコードを更新してください。 – mkrufky

関連する問題