2011-10-26 3 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 개의 스레드를 필요로한다는 것을 의미합니까? 두 번째 스레드 (비동기 작업)가 실행되는 동안 첫 번째 스레드를 일시 중단 할 수있는 방법이 있습니까? –

+0

'@ async'를 사용하면'@ async'에 의해 주석 처리 된 메소드를 호출하고 즉시 반환하는 스레드와'@ async' 메소드에서 실제로 처리중인 다른 스레드가 있습니다. 첫 번째 스레드를 일시 중단하려면 future.get()을 호출하면 결과가 호출 될 때까지 스레드가 차단됩니다. 하지만 그렇게하면 : 와드 다음에'@ async'를 호출하고 future.get()을 호출하면 기술이 많은 메소드 호출의 정상적인 동작을 (거의) 시뮬레이트하기 때문에 완전한'@ ascync' 물건은 쓸모가 없다. 물건. – Ralph

+0

@ danny.lesnik :하지만 계산에 15 분이 걸린다면,이 시간 범위에 대한 연결을 유지하는 것보다 다른 해결책이 필요합니다! – Ralph

관련 문제