使用ServiceStack

时间:2017-09-28 16:05:13

标签: c# jquery ajax servicestack

我有一个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构建日志更新中显示一些内容。

1 个答案:

答案 0 :(得分:2)

感谢Petah在这里的评论,我想通了:jquery ajax, read the stream incrementally?

问题在于它一次写出的字节少于2048个字节。只是为了踢和咯咯笑,我创建了一个4096字节的数组,并多次写出来,有几次睡眠,果然它按预期工作。我花了很长时间才比我应该......