import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import java.util.Stack; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import weblogic.servlet.FutureResponseServlet; import weblogic.servlet.FutureServletResponse; // An AsynchronousServlet that handles HTTP requests from a "separate" thread and // not the execute thread used to invoke this servlet. public class AsynchronousServerResponseServlet extends FutureResponseServlet { private final Notifier notifier; public AsynchronousServerResponseServlet() { this.notifier = new Notifier(); this.notifier.start(); } public void service(HttpServletRequest request, FutureServletResponse response) throws IOException,ServletException { // push this client's request to a buffer and return immediately. // asynchronous processing occurs in the run method of the Notifier Thread notifier.poll(request, response); } class Notifier extends Thread { private static Stack clients = new Stack(); void poll (HttpServletRequest request, FutureServletResponse response) { clients.push(new Client(request, response)); } public void run() { while (!clients.empty()) { Client client = null; try{ client = (Client) clients.pop(); PrintWriter pw = client.response.getWriter(); for(int j = 0; j < 10; j++) { pw.println("Time is:" + new Date() + ""); pw.flush(); } pw.close(); } catch(Throwable t) { t.printStackTrace(); } finally { try { client.response.send(); } catch(IOException ioe) { ioe.printStackTrace(); } } } } } // inner class that holds o-n to the clients http request and response class Client { private HttpServletRequest request; private FutureServletResponse response; private Client(HttpServletRequest request, FutureServletResponse response) { this.request = request; this.response = response; } }
|
可以看出,该例子非常简单。AsynchronousServerResponseServlet类扩展了FutureResponseServlet,并重写了service方法。只使用一个线程(即Notifier类)来处理所有的客户端连接响应。对于每个HTTP请求,servlet向Notifier线程注册套接字连接,然后返回。异步事件被交付给客户端,而持久性套接字连接被维持。
单个线程可管理多个客户端连接!run()方法可用于根据某种消息选择条件回调事件到客户端。该例子只执行了一个服务器端的push操作,有些过分简单了。线程池可被用于某些类型的事件处理。
总而言之,在处理长期运行的任务时,FutureResponseServlet是一个好特性,它允许开发人员提高性能,在独立的线程中处理响应,并将开销降至最低。在构建异步应用程序时,该方法支持可伸缩性。
【相关文章】