给定的是一个基于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
}
就像我在here中看到的那样:
output.append(IOUtils.toString(proc.getInputStream(), "UTF-8"));
浏览器从滞后时间恢复得更快。
显然,还不够。如果允许代码运行n=5 seconds
,并且代码在<n seconds
中执行,则浏览器也会滞后<n seconds
。
问题:我可以用什么方法来规避这个问题?我正在考虑部分发送输出块,以便页面立即收到响应,其余的输出将跟随。如果这是一个很好的方法,我如何在jquery和spring控制器中配置?
或者更重要的是,有更好的方法吗?
P.S。:我确信InputStream的附加是问题所在,因为注释掉行会消除延迟。