Severlet异步长连接调试成功示例

Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
    
  
  <servlet-mapping>
    <servlet-name>PushAction</servlet-name>
    <url-pattern>/PushAction</url-pattern>
  </servlet-mapping>

  <servlet>
    <description></description>
    <display-name>PushAction</display-name>
    <servlet-name>PushAction</servlet-name>
    <servlet-class>org.nipc.PushAction</servlet-class>
    <async-supported>true</async-supported>
  </servlet>
  
  <listener>
    <listener-class>org.nipc.PushListener</listener-class>
  </listener>
</web-app>

PushAction.java
package org.nipc;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Servlet implementation class PushAction
 */
//@WebServlet(urlPatterns = { "/PushAction" }, asyncSupported = true)
public class PushAction extends HttpServlet {
	private static final long serialVersionUID = 1L;
	
//	private static final Logger logger = LoggerFactory.getLogger(PushAction.class);
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public PushAction() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.setHeader("Cache-Control", "private");
		response.setHeader("Pragma", "no-cache");
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		final PrintWriter writer = response.getWriter();

		// 创建Comet Iframe
		writer.println("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">");
		writer.println("<script type=\"text/javascript\">var comet = window.parent.comet;</script>");
		writer.flush();

//		((org.apache.catalina.connector.Request)request).setAsyncSupported(true);
		final AsyncContext ac = request.startAsync();
		ac.setTimeout(10 * 60 * 1000);// 10分钟时间;tomcat7下默认为10000毫秒

		ac.addListener(new AsyncListener() {
			public void onComplete(AsyncEvent event) throws IOException {
//				logger.info("the event : " + event.toString() + " is complete now !");
				PushListener.ASYNC_AJAX_QUEUE.remove(ac);
			}

			public void onTimeout(AsyncEvent event) throws IOException {
//				logger.info("the event : " + event.toString() + " is timeout now !");

				// 尝试向客户端发送超时方法调用,客户端会再次请求/blogpush,周而复始
//				logger.info("try to notify the client the connection is timeout now ...");
				String alertStr = "time out";
				writer.println(alertStr);
				writer.flush();
				writer.close();

				PushListener.ASYNC_AJAX_QUEUE.remove(ac);
			}

			public void onError(AsyncEvent event) throws IOException {
//				logger.info("the event : " + event.toString() + " is error now !");
				PushListener.ASYNC_AJAX_QUEUE.remove(ac);
			}

			public void onStartAsync(AsyncEvent event) throws IOException {
//				logger.info("the event : " + event.toString() + " is Start Async now !");
			}
			
		});

		PushListener.ASYNC_AJAX_QUEUE.add(ac);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

}


PushListener
package org.nipc;

import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.LinkedBlockingDeque;

import javax.servlet.AsyncContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Application Lifecycle Listener implementation class PushListener
 *
 */
//@WebListener
public class PushListener implements ServletContextListener {
	
//	private static final Logger logger = LoggerFactory.getLogger(PushListener.class);
	public static BlockingQueue<String> MSG_QUEUE = new LinkedBlockingDeque<String>();
	public static final Queue<AsyncContext> ASYNC_AJAX_QUEUE = new ConcurrentLinkedQueue<AsyncContext>();

	/**
     * @see ServletContextListener#contextInitialized(ServletContextEvent)
     */
    public void contextInitialized(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
//    	logger.info("context is initialized!");
    	  // 启动一个线程处理线程队列
    	new Thread(runnable).start();
    }

	/**
     * @see ServletContextListener#contextDestroyed(ServletContextEvent)
     */
    public void contextDestroyed(ServletContextEvent arg0) {
        // TODO Auto-generated method stub
//    	logger.info("context is destroyed!");
    }
    
    private Runnable runnable = new Runnable() {
    	public void run() {
    		
    		
    		
    		boolean isDone = true;

    		while (isDone) {
    			MSG_QUEUE.add("Hello");
    			MSG_QUEUE.add("Hello");
    			MSG_QUEUE.add("Hello");
    			MSG_QUEUE.add("Hello");
    			if (!MSG_QUEUE.isEmpty()) {
    				try {
//    					logger.info("ASYNC_AJAX_QUEUE size : " + ASYNC_AJAX_QUEUE.size());
    					String msg = MSG_QUEUE.take();

    					if (ASYNC_AJAX_QUEUE.isEmpty()) {
    						continue;
    					}

//    					String targetJSON = getFormatContent(blog);

    					for (AsyncContext context : ASYNC_AJAX_QUEUE) {
    						if (context == null) {
//    							logger.info("the current ASYNC_AJAX_QUEUE is null now !");
    							continue;
    						}
//    						logger.info(context.toString());
    						PrintWriter out = context.getResponse().getWriter();

    						if (out == null) {
//    							logger.info("the current ASYNC_AJAX_QUEUE's PrintWriter is null !");
    							continue;
    						}

    						out.println(msg);
    						out.flush();
    					}
    				} catch (Exception e) {
    					e.printStackTrace();
    					isDone = false;
    				}
    			}
    		}
    	}
    };
	
}


你可能感兴趣的:(Severlet异步长连接调试成功示例)