本文没有使用任何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="<%=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="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="start" onclick="started()">Start</button> <button value="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
服务器时间是:20101125日,221919
服务器时间是:20101125日,221910
服务器时间是:20101125日,221907
服务器时间是:20101125日,221906
服务器时间是:20101125日,221904
服务器时间是:20101125日,221900
服务器时间是:20101125日,221852
服务器时间是:20101125日,221848
服务器时间是:20101125日,221839
服务器时间是:20101125日,221835
服务器时间是:20101125日,221828

服务端显示

1
2
3
4
5
6
7
8
9
10
11
服务器时间是:20101125日,221828
服务器时间是:20101125日,221835
服务器时间是:20101125日,221839
服务器时间是:20101125日,221848
服务器时间是:20101125日,221852
服务器时间是:20101125日,221900
服务器时间是:20101125日,221904
服务器时间是:20101125日,221906
服务器时间是:20101125日,221907
服务器时间是:20101125日,221910
服务器时间是:20101125日,221919

注意我故意将客户端倒过来显示的.  可以看到, 客户端和服务端的数据是完全一致的.

comet, 比想想中的要难搞多了, 我能不能做个框架出来搞定他?
关于comet 框架和服务器, 可以看看 APE(ajax push engine)

Java_模拟comet的实现的更多相关文章

  1. Comet入门及最简单的Java Demo

    在浏览网页的时候,假设有新的消息,怎样接收到?HTTP协议不能由server主动给client发送消息. 1.刷微博.逛论坛贴吧,想看最新的信息怎么办?F5刷新一下就OK了! 2.上面一种方式是被动的 ...

  2. Comet OJ 热身赛(K题)principal(括号匹配问题+stack模拟)

    principal 已经提交 已经通过 23.66% Total Submission:131 Total Accepted:31 题目描述 阿尔比恩王国潜伏着代号白鸽队''的一群间谍.在没有任务的时 ...

  3. Comet OJ - 模拟赛 #2 Day1 比赛总结

    比赛情况 40 + 60 + 0 = 100pts 哎,T1做错了,没有对拍.如果发现错误 \(=>\) 改正 \(=>\) 40->100pts,160pts \(=>\) ...

  4. 基于 Asp.Net的 Comet 技术解析

    Comet技术原理 来自维基百科:Comet是一种用于web的技术,能使服务器能实时地将更新的信息传送到客户端,而无须客户端发出请求,目前有两种实现方式,长轮询和iframe流. 简单的说是一种基于现 ...

  5. 浅入浅出“服务器推送”之一:Comet简介

    最近有个项目,其中有项需求要从服务器端主动向客户端推送数据,本以为很简单,但在实际做的过程中发现很棘手,并没有想象中的简单.从网上搜索学习,发现主流讲的还是Ajax的长轮询技术或者流技术,websoc ...

  6. 探求网页同步提交、ajax和comet不为人知的秘密(上篇)

    标题里的技术都是web开发里最常见的技术,但是我想这些常用的技术有很多细节是很多朋友不太清楚的,理解这些细节是我们深入掌握这些技术的一把钥匙,今天我就讲讲我使用这些技术时体会到的这些细节. 同步提交是 ...

  7. Comet:基于 HTTP 长连接的“服务器推”技术解析

    原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...

  8. comet

    comet 1.简介: 基于 HTTP长连接的“服务器推”技术,是一种新的 Web 应用架构,基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求.C ...

  9. WEB实时聊天 comet推技术

    转自:http://www.cnblogs.com/wodemeng/archive/2012/04/06/2435302.html 今天晚上朋友遇到web服务端推技术的问题,自己就查了下资料,学习了 ...

随机推荐

  1. Nginx - 压缩模块

    1. 前言 在 Nginx 中与网页压缩相关的模块有两个:一个是 HttpGzipModule,另一个是 HttpGzipStaticModule.前者用于启用在文件传输过程中使用 gzip 压缩,而 ...

  2. html5拖拽初窥

    说到拖动,大概有两种方式,一种是js实现,之前已经介绍过,今天来讲解另外一种方式,那就是使用html5实现拖动. css样式 .box { width: 200px; height: 200px; b ...

  3. 触发器中的inserted表和deleted表

    触发器语句中使用了两种特殊的表:deleted 表和 inserted 表.Microsoft? SQL Server 2000 自动创建和管理这些表.可以使用这两个临时的驻留内存的表测试某些数据修改 ...

  4. 《精通Python设计模式》学习结构型之代理模式

    这种模式,总会让人想到SRPING中的AOP, 不同语言有不同的实现方式吧. class SensitiveInfo: def __init__(self): self.users = ['nick' ...

  5. Python类和人类

    Python中的类 俗话说,物以类聚,人以群分,类是什么,类就是一组相同属性的集合.下面来结合人,探讨Python中类和人类的关系. 首先,我们定义一个人的类,如下: class People(obj ...

  6. Keras中RNN不定长输入的处理--padding and masking

    在使用RNN based model处理序列的应用中,如果使用并行运算batch sample,我们几乎一定会遇到变长序列的问题. 通常解决变长的方法主要是将过长的序列截断,将过短序列用0补齐到一个固 ...

  7. 【BZOJ】1336: [Balkan2002]Alien最小圆覆盖

    题解 我们先把所有点random_shuffle一下 然后对前i - 1个点计算一个最小圆覆盖,然后第i个点如果不在这个圆里,那么我们把这个点当成一个新的点,作为圆心,半径为0 从头枚举1 - i - ...

  8. BZOJ 1036: [ZJOI2008]树的统计Count (树链剖分模板题)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 14982  Solved: 6081[Submit ...

  9. linux保证程序单实例运行

    static int proc_detect(const char *procname){ char filename[100] = {0}; sprintf(filename, "%s/% ...

  10. Oracle截取字符串和查找字符串

    oracle 截取字符(substr),检索字符位置(instr) case when then else end语句使用 收藏 常用函数:substr和instr 1.SUBSTR(string,s ...