2015-12-31 3 views
5

私のサーバーに何らかのオーディオをストリーミングしようとしていて、それをユーザーが指定したサービスにストリームしようとすると、ユーザーはsomeHostNameそのタイプの要求をサポートできないことがあります。readable.on( 'end'、...)が決して解凍されない

私の問題は、それが起こるときclientRequest.on('end',..)が解雇されることはありませんということですが、私はそれがsomeHostReqにパイプされていますので、それはsomeHostNameは「間違った」ときめちゃくちゃますこれだと思います。

私の質問は:

は、ストリームclientRequestパイプがそれと間違って何かを持っている場合でも、私はまだclientRequest.on('end',..)が発射されていることをとにかくありますか?

もしそうでない場合:someHostReqで何か問題が起きたことを「すぐに」検出するにはどうすればよいですか? someHostReq.on('error')はしばらくしてから起動しません。

コード:

someHostName = 'somexample.com' 

    function checkIfPaused(request){//every 1 second check .isPaused 
     console.log(request.isPaused()+'>>>>'); 
     setTimeout(function(){checkIfPaused(request)},1000); 
    } 

    router.post('/', function (clientRequest, clientResponse) { 
     clientRequest.on('data', function (chunk) { 
      console.log('pushing data'); 
     }); 

     clientRequest.on('end', function() {//when done streaming audio 
      console.log('im at the end'); 
     }); //end clientRequest.on('end',) 

     options = { 
      hostname: someHostName, method: 'POST', headers: {'Transfer-Encoding': 'chunked'} 
     }; 

     var someHostReq = http.request(options, function(res){ 
      var data = '' 
      someHostReq.on('data',function(chunk){data+=chunk;}); 
      someHostReq.on('end',function(){ 
       console.log('someHostReq.end is called'); 
      }); 
     }); 
     clientRequest.pipe(someHostReq); 
     checkIfPaused(clientRequest); 
    }); 

出力:正しいホスト名の場合は

pushing data 
    . 
    . 
    pushing data 
    false>>> 
    pushing data 
    . 
    . 
    pushing data 
    pushing data 
    false>>> 
    pushing data 
    . 
    . 
    pushing data 
    console.log('im at the end'); 
    true>>> 
    //continues to be true, that's fine 

間違ったホスト名の場合:

pushing data 
    . 
    . 
    pushing data 
    false>>>> 
    pushing data 
    . 
    . 
    pushing data 
    pushing data 
    false>>>> 
    pushing data 
    . 
    . 
    pushing data 
    true>>>> 
    true>>>> 
    true>>>> 
    //it stays true and clientRequest.on('end') is never called 
    //even tho the client is still streaming data, no more "pushing data" appears 

私の質問が重複:

次のいずれかの方法で流れるモードに切り替えることができます。

'data'イベントハンドラを追加してデータを待機します。

resume()メソッドを呼び出して明示的にフローを開きます。

データをWritableに送信するためにpipe()メソッドを呼び出します。

ソース:それはこれと同じではありませんhttps://nodejs.org/api/stream.html#stream_class_stream_readable

+0

あなたは代わりに 'close'を聞いてみましたか? – aarosil

+0

lisyen close threadとは何ですか? – bubakazouba

+0

ストリームは 'close'イベントと' end'イベントを持っています。詳細は[here](https://nodejs.org/api/stream.html#stream_class_stream_readable) – aarosil

答えて

1

間違ったホスト名の場合の動作を追加するのを忘れて、いくつかの問題と思わバッファによって、宛先のストリームバッファがいっぱいの場合(someHostが送信されたデータのチャンクを取得していないため)、パイプは自動的にフローを管理するため、元のストリームを読み続けることはありません。パイプは原点ストリームを読み込んでいないので、決して「終わり」イベントに到達しません。

私はまだclientRequest.on持つことができること(「終了」、...)とにかくあり それと間違って何かを持っている場合であってもストリームclientRequestパイプ を解雇しましたか?

'end'イベントは、データが完全に消費されない限り発生しません。一時停止したストリームで '終了'を得るには、蒸気をflowModeにもう一度設定するか、read()を最後に設定するために、resume()(間違ったホスト名から最初に読み込まないか、もう一度バッファにスタックする)を呼び出す必要があります。

しかし、私は上記のいずれかを行う必要がありますどのように検出するには?

someHostReq.on(「エラー」)は自然な場所ですが、それがアップ火災に時間がかかりすぎる:

まず低タイムアウト要求(以下someHostReq.onより(「エラー」を設定しよう)があなたのために時間がかかると思われるように、トリガーになる)request.setTimeout(timeout[, callback])と、ホスト名が正しいときに失敗しないかどうかを確認します。もしうまくいくならば、callbackまたはtimeoutイベントを使用して、サーバーtimeOutを検出し、上記のテクニックの1つを使用して終了まで検出してください。

タイムアウトソリューションが失敗したか、あなたは、バッファによって立ち往生しているとき推測するclientRequest.on('data')clientRequest.on('end')および/またはclienteRequest.isPausedにフラグをプレイしているユーザーの要件に適合していない場合。あなたが悩んでいると思うときは、上のテクニックの1つを適用してストリームの終わりに到達してください。幸いなことに、バッファ滞留を検出する時間がsomeHostReq.on('error')(おそらく2つのrequest.isPaused() = true、 'data'イベントが滞留しているかどうかを判断するには届きません。

someHostReq で「間違ったことが起こった」ことを「直ちに検出」するにはどうすればよいですか? someHostReq.on( 'error')は、しばらくして の後に出ません。

トリガーが発生したときにエラーが発生します。あなたはすぐにそれを検出することはできません。 ¿ストリームを配信する前にサポートを確認するためのビーコン要求を送信するだけではどうですか?

"ユーザーが指定したChekingサービス..." If OK - >サービスへのユーザー要求ストリームをパイプOR FAIL - >間違ったサービスについてユーザーに通知します。