Servlet3.0 异步处理 页面推送 Comet 实例
2015-02-02 00:31
288 查看
本例参考:http://blog.csdn.net/chenxiang0207/article/details/14054681/
我按照上面博文的思路重新走了一遍
项目结构如下图
![](http://img.blog.csdn.net/20150202003316165?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDQ5NzIyOA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
开启Tomcat
开启一个页面A先访问http://localhost:8080/CometTest/Comet.jsp
再打开一个新的页面B访问http://localhost:8080/CometTest/Test
此时能够看到A的内容不断的增加
PS:若想让onload函数不失效可以把对iframe的src的赋值操作放在onload中,而一开始src为空
项目打包:http://download.csdn.net/detail/u010497228/8415545
我按照上面博文的思路重新走了一遍
项目结构如下图
/** * AsyncServlet * * 支持异步处理的Servlet * 页面中隐藏的iframe通过访问此Servlet来建立HTTP长连接 * 从而后台能实时的推送javascript代码给页面调用 * */ @WebServlet(urlPatterns = "/Async", asyncSupported = true) public class AsyncServlet extends HttpServlet { private static final long serialVersionUID = 822178713133426493L; private final static int DEFAULT_TIME_OUT = 10 * 60 * 1000; @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) { AsyncContext actx = req.startAsync(); actx.setTimeout(DEFAULT_TIME_OUT); actx.addListener(new AsyncListener() { @Override public void onComplete(AsyncEvent arg0) throws IOException { // TODO Auto-generated method stub ClientComet.getInstance().removeAsyncContext(actx); System.out.println("AsyncListener-->onComplete"); } @Override public void onError(AsyncEvent arg0) throws IOException { // TODO Auto-generated method stub ClientComet.getInstance().removeAsyncContext(actx); System.out.println("AsyncListener-->onError"); } @Override public void onStartAsync(AsyncEvent arg0) throws IOException { // TODO Auto-generated method stub System.out.println("AsyncListener-->onStartAsync"); } @Override public void onTimeout(AsyncEvent arg0) throws IOException { // TODO Auto-generated method stub ClientComet.getInstance().removeAsyncContext(actx); System.out.println("AsyncListener-->onTimeout"); } }); ClientComet.getInstance().addAsyncContext(actx); } }
/** * ClientComet * * 管理用户的AsyncContext(添加、删除) * * 通过开启一个线程来不断地从mesgQueue获取javascript 并遍历用户的AsyncContext来吧javascript推送给每个用户 * */ public class ClientComet { private static ClientComet instance; private ConcurrentLinkedQueue<AsyncContext> actxQueue; private LinkedBlockingQueue<Javascript> mesgQueue; private ClientComet() { actxQueue = new ConcurrentLinkedQueue<AsyncContext>(); mesgQueue = new LinkedBlockingQueue<Javascript>(); new ClientCometThread().start(); } public static ClientComet getInstance() { if (instance == null) { instance = new ClientComet(); } return instance; } public void addAsyncContext(AsyncContext actx) { actxQueue.add(actx); } public void removeAsyncContext(AsyncContext actx) { actxQueue.remove(); } public void callClient(Javascript javascript) { mesgQueue.add(javascript); } protected class ClientCometThread extends Thread { @Override public void run() { while (true) { try { Javascript javascript = mesgQueue.take(); for (AsyncContext actx : actxQueue) { PrintWriter writer = actx.getResponse().getWriter(); writer.write(javascript.getScript()); writer.flush(); System.out .println("ClientCometThread-->sendJavaScript"); } } catch (InterruptedException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
/** * Javascript * * 提供将javascript的方法调用补全到一个script标签中的功能 */ public class Javascript { private String script; public Javascript(String func) { script = "<script type='text/javascript'>" + "\n" + "window.parent." + func + "\n" + "</script>" + "\n"; } public String getScript() { return script; } }
/** * TestServlet * * 访问此Servlet能够给ClientComet的mesgQueue添加对象 * */ @WebServlet(urlPatterns = "/Test") public class TestServlet extends HttpServlet { private static final long serialVersionUID = -7817902387051107187L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) { int times = 5; while (--times >= 0) { try { Thread.sleep(5000); ClientComet.getInstance().callClient( new Javascript("append(" + "\'" + new Date().toGMTString() + "\'" + ")")); System.out.println("TestServlet-->callClient"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Comet.jsp <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Comet Test</title> <script type='text/javascript'> function append(str) { var textField = document.getElementById("textField"); textField.innerHTML = textField.innerHTML + str + "<br/>"; }; </script> </head> <body> <!-- textField——用来显示服务器推送的内容 --> <p id="textField"></p> <!-- cometFrame——隐藏的iframe,用来访问AsyncServlet,建立长连接(注意,这样做window.onload的函数将失效,或直到此连接断开才执行) --> <iframe id="cometFrame" style="display: none;" src="/CometTest/Async"></iframe> </body> </html>
开启Tomcat
开启一个页面A先访问http://localhost:8080/CometTest/Comet.jsp
再打开一个新的页面B访问http://localhost:8080/CometTest/Test
此时能够看到A的内容不断的增加
PS:若想让onload函数不失效可以把对iframe的src的赋值操作放在onload中,而一开始src为空
项目打包:http://download.csdn.net/detail/u010497228/8415545
相关文章推荐
- SpringMvc4.x高级配置(四):服务器端推送技术之Servlet3.0+异步方法处理
- comet4j java服务端推送消息到web页面实例
- servlet3.0新特性Servlet3.0引入的若干重要新特性,包括异步处理、新增的注解支持、可插性支持等等,为读者顺利向新版本过渡扫清障
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- 测试:Servlet 3.0实战:异步处理特性应用
- servlet3.0新特性Servlet3.0引入的若干重要新特性,包括异步处理、新增的注解支持、可插性支持等等
- comet4j Java 服务端推送消息到web页面实例
- Servlet3.0新功能: 异步处理
- Servlet 3.0中的异步处理
- tomcat6的servlet异步处理comet技术
- comet4j java服务端推送消息到web页面实例
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- Servlet 3.0 实战:异步 Servlet 与 Comet 风格应用程序
- Ajax 轮询以及Comet模式—写在Servlet 3.0发布之前
- servlet处理表单数据之实例开发(1)
- servlet中处理用户非法登录页面
- iFrame应用实例讲解——页面无需刷新的异步文件上传!