2011-10-26 49 views
5

我有我的控制器,其執行@Async任務在Spring MVC返回@Async方法的結果並返回給Ajax客戶

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

方法的執行時間長達1O分鐘內的一些方法。我所需要做的只是將結果返回到將使用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個線程用於請求,另一個用於異步任務?有沒有辦法掛起第一個線程而第二個線程(異步任務)執行? –

+0

如果你使用'@ async',那麼你有兩個線程,一個調用'@ async'註釋的方法並立即返回,另一個線程真的在'@ async'方法中執行。要暫停第一個線程,只需調用future.get(),就會阻塞該線程,直到結果被調用。但是如果你這樣做:調用'@ async'並直接在後面調用future.get(),那麼完整的'@ ascync'就沒用了,因爲你用很多技術模擬(幾乎)方法調用的正常行爲東東。 – Ralph

+0

@ danny.lesnik:但是如果你的計算需要15分鐘,那麼你真的需要另一個解決方案,而不是在這段時間內保持連接! – Ralph