我正在尝试使用jquery和aysnc servlet添加longpolling,javascript ajax请求每分钟超时,通过创建一个新请求,servlet设置超时10分钟,但jquery ajax在一分钟内超时, 只有当tomcat落后于apache时才会发生这种情况,我使用的是mod_jk连接器。
的javascript
var MessagePanel ={
unreadMsg:function(){
var markup='<div> You have unread messages </div>'
var my_dialog =$(markup).dialog({
position:'right'
,title:'Unread Messages'
});
my_dialog.dialog('widget').zIndex(25000);
},
newMsg:function(){
var markup='<div> You have a new message </div>'
var my_dialog =$(markup).dialog({
position:'right top'
,title:'New Message'
});
my_dialog.dialog('widget').zIndex(25000);
}
,longPoll:function(channel){
$.ajax({
url: "/myapp/cometmsg",
success: function(data){
if(data){
if('new_message'===data.trim()){
MessagePanel.newMsg();
}
}
},
error: function(err) {
console.log(" long poll error "+err);
},
type: "GET",
data: {name:channel,timestamp: new Date().getTime()}
,complete:function(){
MessagePanel.longPoll(channel)
}
});
}
}
服务器端代码
public class MessageNotificationServlet extends HttpServlet {
static Logger logger= Logger.getLogger(MessageNotificationServlet.class);
private Queue<AsyncContext> asyncContexts = new ConcurrentLinkedQueue<AsyncContext>();
static BlockingQueue<String> messages = new LinkedBlockingQueue<String>();
ExecutorService executorService;
public static void addMessage(String msg){
try{
logger.debug(" receiving new msg"+msg);
messages.add(msg);
logger.debug(" add new msg"+msg);
}catch(Exception e){
throw new RuntimeException(e);
}
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
executorService=Executors.newSingleThreadExecutor();
executorService.submit(new Runnable() {
@Override
public void run() {
while(true){
try{
String message = messages.take();
logger.debug(" processing new message "+message);
for(AsyncContext asyncContext :asyncContexts ){
try{
if(asyncContext.getRequest().getParameter("name").trim().equals(message)){
String paramName=asyncContext.getRequest().getParameter("name").trim();
String timestamp=asyncContext.getRequest().getParameter("timestamp").trim();
try{
logger.debug(" writing to "+paramName +" "+timestamp);
PrintWriter printWriter=asyncContext.getResponse().getWriter();
printWriter.println("new_message");
printWriter.flush();
asyncContext.complete();
logger.debug(" completed async to "+paramName+" "+timestamp);
}catch(Exception e){
//asyncContexts.remove(asyncContext);
logger.debug(" failed writing to async "+paramName +" "+timestamp );
logger.error((" async failed "+paramName +" "+timestamp),e);
}
}
}catch (Exception e) {
asyncContexts.remove(asyncContext);
logger.debug(" error with asyncontext ",e);
}
}
}catch(Exception e){
logger.debug(" error in msg check thread ",e);
}
}
}
});
}
@Override
public void destroy() {
super.destroy();
messages.clear();
asyncContexts.clear();
executorService.shutdownNow();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
if (req.isAsyncStarted()) {
logger.debug(" from doget for already started req ");
response.getWriter().write("asyncResult=" + req.getAttribute("asyncResult"));
}else {
String name=req.getParameter("name");
String timestamp=req.getParameter("timestamp");
logger.debug(" received new request from "+name +" "+timestamp+" "+new Date());
AsyncContext asyncContext=req.startAsync();
asyncContext.getRequest().setAttribute("start_time", new Date());
asyncContext.addListener(new AsyncListener() {
@Override
public void onTimeout(AsyncEvent event) throws IOException {
logger.debug(" timeout occuered for " +event.getAsyncContext().getRequest().getParameter("name") +" "+event.getAsyncContext().getRequest().getParameter("timestamp")+" "+event.getAsyncContext().getRequest().getAttribute("start_time"));
event.getAsyncContext().getResponse().getWriter().write("TIMEOUT");
event.getAsyncContext().complete();
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
logger.debug(" onstart for " +event.getAsyncContext().getRequest().getParameter("name") +" "+event.getAsyncContext().getRequest().getParameter("timestamp") +" "+event.getAsyncContext().getRequest().getAttribute("start_time"));
}
@Override
public void onError(AsyncEvent event) throws IOException {
logger.debug(" error occuered for " +event.getAsyncContext().getRequest().getParameter("name") +" "+event.getAsyncContext().getRequest().getParameter("timestamp") +" "+event.getAsyncContext().getRequest().getAttribute("start_time"));
asyncContexts.remove(event.getAsyncContext());
}
@Override
public void onComplete(AsyncEvent event) throws IOException {
logger.debug(" completed " +event.getAsyncContext().getRequest().getParameter("name")+" "+event.getAsyncContext().getRequest().getParameter("timestamp") +" "+event.getAsyncContext().getRequest().getAttribute("start_time"));
asyncContexts.remove(event.getAsyncContext());
}
});
asyncContext.setTimeout(TimeUnit.MINUTES.toMillis(10));
asyncContexts.add(asyncContext);
}
}
}
MessagePanel.longPoll是函数,我在页面加载时调用。