【发布时间】:2017-09-29 01:26:16
【问题描述】:
我有一个 ServiceStack 服务,它在给定输入文件的情况下在后台执行一个长时间运行(如 10-20 秒)的程序。在客户端,文件被上传到服务,然后文件被传递给可执行文件。我有能力将该可执行文件的输出重定向到一个流,但是当我尝试将该流发送到客户端的 ajax 调用时,它不会开始消耗,直到流完成。我认为我已经正确完成了设置部分内容的所有操作,所以我不确定为什么这不起作用(或者如果这甚至可以通过服务器端的 ServiceStack 和 jQuery 的 ajax在客户端调用)。我的代码如下(稍作修改以删除任何专有内容。但同样的原则适用):
//Service side
public async Task<HttpResult> Post(SomeProcessingRequest request) {
var tempFile = Path.GetTempFileName();
try {
base.Request.Files.FirstNonDefault().SaveTo(tempFile);
log.Info($@"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"); }, $@"-i {tempFile}");
log.Info($@"app complete");
return result;
} finally {
try {
File.Delete(tempFile);
} catch(IOException ex) {
log.Warn($@"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 构建日志实时更新的内容。
【问题讨论】:
标签: c# jquery ajax servicestack