首页 > 代码库 > Java_模拟comet的实现
Java_模拟comet的实现
本文没有使用任何comet服务器, 只是利用tomcat模拟实现了一下comet, 不是真正的comet哦,因为不会有这样的应用场景, 只是模拟实现, 仅供参考.
一. 需求.
实现将服务端的时间推送到客户端, 客户端在得到服务端相应后将时间显示在页面上.
二.实现.
1开发框架: 用jsp+servlet的方法, 用了一个webframework框架, 自己写的, 类似于struts2, 可以的话就把它当作struts2来看吧.
2. jsp代码如下
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | <%@ page language= "java" import= "java.util.*" pageEncoding= "UTF-8" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+ "://" +request.getServerName()+ ":" +request.getServerPort()+path+ "/" ; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <base href=http://www.mamicode.com/ "<%=basePath%>" > <title>My JSP ‘serverTime.jsp‘ starting page</title> <meta http-equiv= "pragma" content= "no-cache" > <meta http-equiv= "cache-control" content= "no-cache" > <meta http-equiv= "expires" content= "0" > <meta http-equiv= "keywords" content= "keyword1,keyword2,keyword3" > <meta http-equiv= "description" content= "This is my page" > <!-- <link rel= "stylesheet" type= "text/css" href=http://www.mamicode.com/ "styles.css" > --> <script type= "text/javascript" > var stop=false; var div= "" ; var inited = false; function init(){ div = document.getElementById( "forDisplay" ); } function stoped(){ stop=true; } function started(){ if (!inited){ init(); inited = true; } stop=false; clear(); ajax(); } function clear(){ if (div){ div.innerHTML= "" ; } } function creatXHR(){ var xmlhttp_request = "" ; try { if ( window.ActiveXObject ){ for ( var i = 5; i; i-- ){ try { if ( i == 2 ){ xmlhttp_request = new ActiveXObject( "Microsoft.XMLHTTP" ); } else { xmlhttp_request = new ActiveXObject( "Msxml2.XMLHTTP." + i + ".0" ); xmlhttp_request.setRequestHeader( "Content-Type" , "text/xml" ); xmlhttp_request.setRequestHeader( "Charset" , "gb2312" ); } break ; } catch (e){ xmlhttp_request = false; } } } else if ( window.XMLHttpRequest ){ xmlhttp_request = new XMLHttpRequest(); } } catch (e){ xmlhttp_request = false; } return xmlhttp_request; } function ajax(){ var xmlhttp_request = creatXHR(); xmlhttp_request.open( ‘GET‘ , ‘ajax.action‘ , true); xmlhttp_request.send(null); xmlhttp_request.onreadystatechange = function (){ if (xmlhttp_request.readyState == 4) { if (xmlhttp_request.status == 200){ var timeStr = xmlhttp_request.responseText; div.innerHTML =timeStr+ "<br/>" +div.innerHTML; } if (!stop){ ajax(); } } } } </script> </head> <body> <button value=http://www.mamicode.com/ "start" onclick= "started()" >Start</button> <button value=http://www.mamicode.com/ "stop" onclick= "stoped()" >Stop</button> <BR/> <div id= "forDisplay" ></div> </body> </html> |
前面我有篇文章谈到, 客户端做的事情很简单, 就是提交ajax请求, 等待服务端返回数据, 展示完后继续请求即可. 我这里做了个控制, 可以自由停止.
3.服务端代码
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package org.jiacheo.webframework.test; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import org.jiacheo.web.framework.Template; import org.jiacheo.web.framework.context.TemplateContext; public class Time4Ajax implements Template { @Override public String execute() { try { PrintWriter writer =TemplateContext.getResponse().getWriter(); Random random = new Random(); int second = random.nextInt( 10 ); iambusy(second); Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat( "服务器时间是:yyyy年MM月dd日,HH时mm分ss秒" ); System.out.println(format.format(date)); writer.println(format.format(date)); writer.flush(); writer.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null ; } private void iambusy( int second) { // TODO Auto-generated method stub final int oneSecond = 1000 ; try { Thread.sleep(oneSecond*second); } catch (InterruptedException e) { //ignore it } } } |
每次请求都随机sleep几秒, 模拟在处理事务, 得到处理完了再返回数据, 也就是吧服务端的时间推送到客户端去.
这样就可以模拟comet的实现了. 但这里跟comet最大的不同是, 服务端不是主动主动阻塞的, 如何做到服务端主动阻塞, 等待有了返回结果再返回给客户端, 这个服务端实现的一个难点.我之前提到可以用时间模型, 但是事件模型能做的东西实在太少了, 要是能从规范上搞定, 那这个实现就方便很多了.
测试结果:
客户端显示:
?
1 2 3 4 5 6 7 8 9 10 11 | 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 19 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 10 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 07 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 06 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 04 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 00 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 52 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 48 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 39 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 35 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 28 秒 |
服务端显示
?
1 2 3 4 5 6 7 8 9 10 11 | 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 28 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 35 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 39 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 48 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 18 分 52 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 00 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 04 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 06 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 07 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 10 秒 服务器时间是: 2010 年 11 月 25 日, 22 时 19 分 19 秒 |
注意我故意将客户端倒过来显示的. 可以看到, 客户端和服务端的数据是完全一致的.
comet, 比想想中的要难搞多了, 我能不能做个框架出来搞定他?
关于comet 框架和服务器, 可以看看 APE(ajax push engine)
Java_模拟comet的实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。