2011-10-26 4 views
5

私はコントローラ内で@Asyncタスクを実行するいくつかのメソッドを持っています。Spring MVCで@Asyncメソッドの結果を返し、それをAjaxクライアントに返します。

@Async 
public Future<String> getResultFromServer(){ 
    String result = ...... 
    return new AsyncResult<String>(result); 
} 

メソッドの実行時間は最大1分です。私がする必要があるのは、AJAX/JQueryを使用して接続されるクライアント側に結果を返すことだけです。

@Asyncメソッドが実行されたかどうかにかかわらず、クライアントが毎秒私のサーバーを要求しないようにしたい。私は接続を開いたままにしておき、結果をサーバーに「プッシュ」するだけです。

@RequestMapping(value="/async.do", method=RequestMethod.POST) 
public void getResult(HttpServletResponse res){ 
    String result = null; 
    PrintWriter out = res.getWriter(); 
    Future<String> future = getResultFromServer(); 
    try { 
     if (future.isDone()) 
      result = future.get(); 
     out.println(result); 
     out.close(); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } catch (ExecutionException e) { 
     e.printStackTrace(); 
    } 
} 

これはComitモデルに非常に近いと理解していますが、私は一般的に彗星に精通していません。

私の質問は、JavaScript/JQueryを使用してクライアント側で接続を開いたままにする方法です。

私の@RequestMapping(value="/async.do", method=RequestMethod.POST)メソッドは結果をクライアントにプッシュしますか?

+1

最終的にこの/パート2をどのように解決しましたか? – happybuddha

答えて

2

最も簡単な方法は、メソッドを非同期で呼び出すのではなく、同期メソッドで直接コントローラから呼び出すことです。

次に、メソッドの結果が計算されるまで要求が「待機」し、要求が作成されるとすぐに返される必要があります。

もちろん、これは接続がジョブの所要時間(1分)で開かれることを意味します。

+0

答えをありがとう、直接メソッドを実行するアイデアについては、別の懸念があります。私が理解する限り、Tomcatは私の要求をHTTP接続用に別のスレッドで処理します。私の要求が15分間続くと、Tomcatのスレッドがその時間すべて実行されることを意味しますか?この操作では、要求に対して2つのスレッドが必要で、非同期タスクに2つのスレッドが必要ですか? 2番目のスレッド(非同期タスク)が実行されている間に、最初のスレッドを中断する方法はありますか? –

+0

'@ async'を使うと、' @ async'でアノテーションされたメソッドを呼び出し、即座に返るメソッドと、 '@ async'メソッドで実際にやっているメソッドの2つのスレッドがあります。最初のスレッドを中断するには、単にfuture.get()を呼び出します。これは結果が呼び出されるまでスレッドをブロックします。しかし、もしあなたがそうしたなら:あなたは(ほとんど)技術的な多くのメソッド呼出しの通常の振る舞いをシミュレートするので、 '@ async'を呼び出して、ワードの後に​​future.get()を直接呼び出すと、' @ ascync'の完全なものは役に立ちません。もの。 – Ralph

+0

@ danny.lesnik:しかし、計算に15分かかる場合は、この時間間隔の接続を保留する以外の解決策が本当に必要です。 – Ralph

関連する問題