Spring MVC 3.2 で、テキストエリアを持つ (JSP) Web ページを作成しました。クライアントから、サーバー上で実行されるコンソール アプリケーションを起動します。このコンソール アプリの出力をブラウザーのテキスト領域に表示したいと考えています。
コンソールの cmd 出力を示す応答が得られます。ただし、問題は、プログラムの終了後にコンソール出力が一度に表示されることです。各出力行がすぐにテキストエリアを更新するのを見たいです。
コントローラーコード
@RequestMapping(value = "/url", method = RequestMethod.POST)
public void Console(HttpServletResponse response) throws Exception {
Process p = Runtime.getRuntime().exec("cmd /C cd \"C:\\appl\"" + "&" + "consoleApp.bat");
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
response.getWriter().println(line);
response.getWriter().flush();
logger.info(line);
}
}
クライアントコード
$(function(){
$('#someTag').click(function(){
$.post("url","data",
function(response){
$('#console').append(response);
var psconsole = $('#console');
psconsole.scrollTop(
psconsole[0].scrollHeight - (psconsole.height() - 10)
);
});
});
});
アップデート
ポーリング メカニズムを実装しました (以下のコードを参照)。ただし、これは私が考えていたよりも間接的なアプローチです。誰かがよりクリーンな実装または単純なサーバー プッシュの例を入手した場合は、それを見たいと思います。
コントローラーコード
@RequestMapping(value = "/deploy", method = RequestMethod.POST)
public @ResponseBody String console(@RequestParam(value="request", required=false) String request) throws Exception {
logger.info("status " + request);
if(request.equals("start")){
Process p = Runtime.getRuntime().exec("cmd /C dir C:\\");
in = new BufferedReader(new InputStreamReader(p.getInputStream()));
return "started";
}
while ((line = in.readLine()) != null) {
logger.info(line);
return line;
}
logger.info("status finished");
return "finished";
}
クライアントコード
var status = "start";
var console = $('#console');
console.append("starting" + '\r');
(function poll(){
setTimeout(function(){
$.ajax({
url: "deploy",
data: {request: status},
type: "post",
success: function(data){
if(data.indexOf("finished") !== -1){
console.append(data + '\r');
setTimeout(function()
{console.scrollTop(console[0].scrollHeight - console.height());}
, 20);
status = "finished";
}else if(data === ""){
console.append('\r');
setTimeout(function()
{console.scrollTop(console[0].scrollHeight - console.height());}
, 20);
status = "processing";
poll();
}else{
console.append(data + '\r');
setTimeout(function()
{console.scrollTop(console[0].scrollHeight - console.height());}
, 20);
status = "processing";
poll();
}
}, dataType: "text"});
}, 100);
})();