1

Given 是一个基于 Spring MVC 的 Webapp,它执行接收到的客户端源代码(用 java 编写)并返回它的输出。

在 jsp 中,我有一个 jquery 函数,它通过以下方式将客户端代码发送到服务器:

$.post(contextPath('/submit/run'), {
    className: className, // somewhere blah blah
    source: code,
    args: args,
    stdin: stdin
}, function(data) {
    log(data);
});

收到:

@RequestMapping(value = "/run", method = RequestMethod.POST)
public @ResponseBody String run(@RequestParam("className") String className,
                                @RequestParam("source") String source,
                                @RequestParam("args") String args,
                                @RequestParam("stdin") String stdin){
    final CodeRunner runner = ...; // Compiles, Executes..
    return runner.run(); // Then returns output from StdOut
}

一切正常,但是。运行器可以在定义的时间内执行代码,即:如果超过n秒则杀死线程。但是,如果客户端代码执行带有循环的代码,<~n sec例如:

for(int i = 0; i < 200000; i++) 
    System.out.println("Not so infinite loop.");// runs 0.87 second, but prints a lot

浏览器滞后,因为它似乎在等待响应。

我最初认为,也许我将输出附加到运行器内的字符串生成器的方式是一个循环。所以我改变了这个:

String line;
while((line = reader.readline()) != null){
    output.append(line).append("\r\n"); // output = StringBuilder, reader = BufferedReader
}

对此,正如我在这里看到的:

output.append(IOUtils.toString(proc.getInputStream(), "UTF-8"));

浏览器从滞后中恢复得更快。

显然,还是不够。如果允许代码在 中运行n=5 seconds,并且在 中执行<n seconds,那么浏览器也会滞后<n seconds

问题:我可以使用什么方法来规避这个问题?我正在考虑部分发送输出块,以便页面立即收到响应,其余的输出将随之而来。如果这是一个好方法,我该如何在 jquery 和 spring 控制器中进行配置?

或者更重要的是,有没有更好的方法?

PS:我确信 InputStream 的附加是问题,因为注释掉行会消除滞后。

4

0 回答 0