I am trying to add longpolling using jquery and aysnc servlet, the javascript ajax request is timing out every minute, there by creating a new request, servlet sets timeout for 10 minutes but jquery ajax times out in one minute, this happens only when tomcat is behind apache,I am using mod_jk connector.
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)
}
});
}
}
server side code
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 is the function , I call on page load.