Servlet 3.0:无法发送异步响应?

Servlet 3.0:无法发送异步响应?

问题描述:

我无法为用户建立AsyncContext并使用它们向他们推送通知。在页面加载我有一些jQuery代码来发送请求:Servlet 3.0:无法发送异步响应?

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

而在“的TestServlet”我有这样的代码在doPost方法:

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 

然而,根据Opera蜻蜓(调试像Firebug这样的工具),看起来服务器在发送请求后发送大约30000ms的HTTP 500响应。

任何使用userAsyncContext.getResponse()。getWriter()。print(SOME_JSON)创建并在HTTP 500响应未被浏览器接收之前发送的响应,我不知道为什么。仅当处理AsyncContext的“if”语句中的所有代码都不存在时,浏览器才会收到使用常规响应对象发送响应(response.print(SOME_JSON))。

有人可以帮我吗?我有一种感觉,这是因为我误解了异步API的工作原理。我认为我可以将这些AsyncContext存储在全局映射中,然后检索它们并使用它们的响应对象将事物推送到客户端。但是,它似乎并不像AsyncContexts可以写回客户端。

任何帮助将被处理。

我解决了这个问题。它好像有几个问题错了我的做法:

  1. GlassFish中,AsyncContext对象均具有30000毫秒(0.5分钟),默认的超时时间。一旦这段时间到期,整个响应都会返回给客户端,这意味着您将无法再使用它。

    如果您正在实施长轮询,这可能不是什么大问题(因为您最终会在响应之后发送另一个请求),但是如果您希望实现流式传输(发送数据返回到客户端没有提交响应),你会想要增加超时时间,或者一起摆脱它。 这可以通过AsyncContext的.setTimeout()方法来完成。请注意,尽管spec指出:“超时值为零或更低表示没有超时。”,Glassfish(目前)似乎将0解释为“立即响应要求”,任何负数解释为“无超时”。

  2. 如果你实现流,你必须使用的PrintWriter的.flush()方法,你使用它的.print().println().write()方法将数据写入完成后,将数据推送到客户端。在客户端,如果你已经对数据进行了流式处理,它将触发3的readyState(“交互式”,这意味着浏览器正在接收响应)。如果你使用jQuery,没有简单的方法来处理3的readyStates,所以你将不得不恢复到正常的Javascript,以便发送请求并处理响应,如果你正在实现流。

我注意到,在Glassfish的,如果你使用AsyncContext和使用.setTimeOut()为负数的连接反正坏了,要解决这个问题,我不得不去我的GlassFish管理web界面:asadmin的设置 configs.config.server-config.network-config.protocols.protocol。HTTP侦听器1.http。并将超时设置为-1。所有这些以避免玻璃鱼在30秒后完成连接。