2011-05-10 3 views
1

사용자를 위해 AsyncContexts를 설정하고이를 사용하여 알림을 푸는 데 문제가 있습니다. 오페라 잠자리 (디버깅에 따라, 그러나Servlet 3.0 : 비동기 응답을 보낼 수 없습니까?

HttpSession userSession = request.getSession(); 
String userIDString = userSession.getAttribute("id").toString(); 

String paramAction = request.getParameter("action"); 

if(paramAction.equals("registerAsynchronousContext")) 
{    
    AsyncContext userAsyncContext = request.startAsync(); 

    HashMap<String, AsyncContext> userAsynchronousContextHashMap = (HashMap<String, AsyncContext>)getServletContext().getAttribute("userAsynchronousContextHashMap"); 
    userAsynchronousContextHashMap.put(userIDString, userAsyncContext); 
    getServletContext().setAttribute("userAsynchronousContextHashMap", userAsynchronousContextHashMap); 

    System.out.println("Put asynchronous request in global map"); 
} 

    //userAsynchronousContextHashMap is created by a ContextListener on the start of the web-app 

:

$.post("TestServlet",{ 
    action: "registerAsynchronousContext" 
     },function(data, textStatus, jqXHR){ 
      alert("Server received async request"); //Placed here for debugging 
    }, "json"); 

그리고 "TestServlet"에

나는 이것을 doPost 메소드의 코드를 가지고 : 페이지로드에 나는 요청을 보낼 수있는 몇 가지 jQuery 코드를 Firebug와 같은 도구), 요청이 전송 된 후 서버가 약 30000ms의 HTTP 500 응답을 보내는 것처럼 보입니다.

userAsyncContext.getResponse(). getWriter(). print (SOME_JSON)로 생성되고 HTTP 500 응답 이전에 전송 된 응답은 브라우저에서 수신되지 않으며 이유를 알지 못합니다. AsyncContext를 처리하는 "if"문에있는 모든 코드가없는 경우에만 일반 응답 객체를 사용하여 응답 (response.print (SOME_JSON))을 브라우저에 수신합니다.

누군가 나를 도울 수 있습니까? 이 비동기 API 작동 방식에 대한 오해로 인한 느낌이 들었습니다. 나는이 AsyncContext를 글로벌 맵에 저장 한 다음 검색하여 클라이언트에 응답 객체를 사용하여 클라이언트에 푸시 할 수 있다고 생각했습니다. 그러나 AsyncContext가 클라이언트에 다시 쓸 수있는 것처럼 보이지는 않습니다.

도움이 필요합니다.

답변

5

나는이 문제를 해결했다. 글래스 피시에서

  1. AsyncContext 모두 30,000 밀리 초 (0.5 분)의 기본 시간 초과 기간이 객체 : 여러 나의 접근 방식 문제 문제가있는 것처럼 보인다. 이 기간이 만료되면 전체 응답이 다시 클라이언트에 위임되므로 다시 사용할 수 없습니다.

    롱 폴링을 구현하는 경우 문제가별로 없을 수도 있지만 (응답 이후에 다른 요청을 보내 게되므로), 스트리밍을 구현하려는 경우 (데이터를 클라이언트가 응답을하지 않고) 시간 초과를 늘리거나 함께 제거 할 수 있습니다. 이 작업은 AsyncContext의 .setTimeout() 메서드를 사용하여 수행 할 수 있습니다. "0 시간 이하의 시간 제한 값은 시간 제한 없음을 나타냅니다."라고 말하면서 GlassFish는 "즉각적인 응답이 필요합니다"로 0을 해석하고 음수는 "시간 초과 없음"으로 해석합니다. 당신이 스트리밍을 구현하는 경우

  2. , 당신은 데이터를 기록하기 위해 .print().println() 또는 .write() 방법을 사용하여 완료 후 클라이언트에 데이터를 밀어의 PrintWriter의 .flush() 방법을 사용해야합니다.

  3. 클라이언트 측에서 데이터를 스트리밍하면 readyState가 3 ("대화식", 즉 브라우저가 응답 수신 중임을 의미)으로 트리거됩니다. jQuery를 사용하는 경우 readyStates를 3으로 처리하는 쉬운 방법이 없으므로 스트리밍을 구현하는 경우 요청을 보내고 응답을 처리하기 위해 일반 Javascript로 되돌려 야합니다.

2

것은 내가 글래스 피시 당신이 AsyncContext를 사용하는 경우 내 글래스 피시 관리 웹 피규에 가서 내가 가진이 문제를 해결하기 위해, 연결이 어쨌든 고장 음수에 .setTimeOut()를 사용하는 것으로 나타났습니다 : 및 asadmin는 설정 configs.config.server-config.network-config.protocols.protocol.http-listener-1.http. 타임 아웃을 -1로 설정하십시오. 글래스 피시가 30 초 후에 연결을 마무리하는 것을 피하기 위해이 모든 것.