2017-09-28 9 views
2

私は、入力ファイルを指定して、長時間実行する(10-20秒のような)プログラムを実行しています。クライアント側では、ファイルがサービスにアップロードされ、ファイルは実行可能ファイルに渡されます。実行可能ファイルの出力をストリームにリダイレクトする機能がありますが、ストリームをクライアント側でAjax呼び出しに送信しようとすると、ストリームが完了するまで消費が開始されません。 I think私は部分的なコンテンツをセットアップするためにすべてを正しく行ったので、なぜこれが動作していないのか分かりません(またはこれがサーバー側のServiceStackとクライアント側のjQueryのajax呼び出し)。私のコードは、以下の(任意の独自のものを削除するには、わずかに修正同じ原理がが適用されます。)されていますServiceStackを使用したajaxコールのコマンド出力ストリーム

//Service side 
public async Task<HttpResult> Post(SomeProcessingRequest request) { 
    var tempFile = Path.GetTempFileName(); 
    try { 
     base.Request.Files.FirstNonDefault().SaveTo(tempFile); 
     log.Info([email protected]"Launching application"); 
     var ms = new MemoryStream(); 
     var sw = new StreamWriter(ms); 
     var result = new HttpResult(ms, "text"); 
     //launches the app and pipes the output to the lambda (just a wrapper for Process) 
     await env.LaunchApplication("myapp.exe", false, (msg) => { 
      if (msg != null) { 
       ms.Write(msg); 
       ms.Flush(); 
      } 
     }, (msg) => {},() => { },() => { throw new Exception("application failed"); }, [email protected]"-i {tempFile}"); 
     log.Info([email protected]"app complete"); 
     return result; 
    } finally { 
     try { 
      File.Delete(tempFile); 
     } catch(IOException ex) { 
      log.Warn([email protected]"Could not delete temp file {tempFile}"); 
     } 
    } 
} 

とクライアント側のAJAX呼び出し:

this.ImportCommand = (element, event) => { 
    var last_response_len = false; 
    var fileInput = $('#fileInput'); 
    var file = fileInput.get(0).files[0]; 
    var formData = new FormData(); 
    formData.append('file', file); 
    $.ajax({ 
     url: `/*url here*/`, 
     type: 'POST', 
     data: formData, 
     cache: false, 
     contentType: false, 
     processData: false, 
     success: (res) => { 
      console.log("app call complete"); 
      self.RefreshCommand(); 
     }, 
     xhrFields: { 
      onprogress: (e) => { 
       console.log(e.currentTarget.response); 
       var this_response, response = e.currentTarget.response; 
       if (last_response_len === false) { 
        this_response = response; 
        last_response_len = response.length; 
       } else { 
        this_response = response.substring(last_response_len); 
        last_response_len = response.length; 
       } 
       self.outputLog += this_response; 
      } 
     } 
    }); 

だからもう一度、すべてが動作するように表示され、除きますコマンドからの出力をライブストリーミングするのではなく、すべてをストリームに追加してから、応答がサーバーから来たときにストリームをダンプします。私がServiceStack/jQueryで達成しようとしていることはありますか?基本的には、Jenkinsがログを更新してライブを更新する行に沿って何かを表示したいと思います。

答えて

2

私はここPetahさんのコメントのおかげでそれを考え出し:jquery ajax, read the stream incrementally?

問題は、それが一度に未満2048バイトを書いていたということでした。私は4096バイトの配列を作成し、それを複数回書きました。数回眠ってしまいましたが、期待通りに動作しました。私はそれ以上に多くの時間を費やしました。

+0

MemoryStreamを使用する代わりに、Response.OutputStreamに直接書き込む必要がありました。私はそれが正直であると仮定します。 –

関連する問題