`
only_java
  • 浏览: 112409 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

comet push学习记录

    博客分类:
  • j2se
阅读更多

 

   Comet push技术最根本的还是socket通信。它将客户端会话注册到一个map中,服务端通过客户端传入的JESSIONID来识别客户端,服务端不断给map中所有JESSIONID下的session注入数据。另一方面一旦有客户端链接,服务端就可以通过JESSIONID不断读session数据,然后发送给客户端。当然这种技术有缺陷,不适合高并发的访问。因为客户端和服务器端建立的是长连接,一旦连接过多服务端很难承受。

 

 这里分服务端和客户端分别说明:

服务端

初始化阶段:

启动tomcat服务时,利用监听启动serversocket接口,并监听客户端请求 。同时还需启动一个session监听接口,当客户端访问时,session监听器通过sessionMap,将客户端发送关来的会话session中JSESSIONID作为sessionMap的key,session作为value.其中JSESSIONID是客户端的唯一标识。Sesssion监听程序大概如下:

public class CometSessionListener implements javax.servlet.http.HttpSessionListener{

    

    public void sessionCreated(HttpSessionEvent event) {

       

       SessionQueue.put(event.getSession().getId(), event.getSession());

    }

 

    public void sessionDestroyed(HttpSessionEvent event) {

       System.out.println("sessionid="+event.getSession().getId());

       

       SessionQueue.remove(event.getSession().getId());

    }

}

 

 

数据推送到客户端阶段:

下面两个步骤是可以同时进行的

1.数据存放到sessionMap

sessionMap是保存发往每个客户端数据的容器。一旦服务端有新数据data,则将新数据data写入到每个客户端的session(即sessionMap.get(JSESSIONID))队列中。代码表示大概如下:

//获得sessionMap

        LinkedHashMap sessions = SessionQueue.getSession();     Collection c = sessions.values();

       Iterator iter = c.iterator();

    

       while (iter.hasNext()) {

           //通过循环获得每个session的值

           HttpSession session = (HttpSession) iter.next();

           PriorityQueue<Message> queue = (PriorityQueue<Message>) session

                  .getAttribute("message");

           if (queue == null) {

              queue = new PriorityQueue<Message>();

//将队列PriorityQueue赋值给session,session名为message

              session.setAttribute("message", queue);

           }

//将消息写入队列

           queue.add(msg);

 

    }

 

2.数据从sessionMap中取数据

 当服务端socket监听到有客户端连接时,启动一个线程来处理,在此线程的run方法中,首先获取客户端http头部信息,解析出JESSIONID的值,然后通过死循环来不断取sessionMap中JESSSIONID下的消息,然后发送给客户端,当然发送给客户端之前的数据最终要转化为js,通过调用客户端js来改变html页面。代码表示大概如下:

HttpSession session = SessionQueue.get(getSid());

                   queue = (PriorityQueue<Message>) session

                           .getAttribute("message");

 

Message msg = null;

                

try {

     msg = queue.remove();

  } catch (Exception e) {

     msg = null;

  }

  if (msg != null) {

         OutputStream out = sc.getOutputStream();

         out.write("HTTP/1.1 200 OK\r\n".getBytes());

           out.write("Content-Type:text/html;charset=GBK\r\n\r\n".getBytes());

         String content = "<script language='javascript'>window.parent.showMsg({user:'"

                                 + msg.getUser()

                                 + "',msg:'"

                                 + msg.getMsg() + "'});</script>";

                          out.write(content.getBytes());

                          out.flush();

                            

}

 

1.  客户端

客户端就比较简单了,因为它是被动的,所以只要在页面初始化时发送一个http请求到服务端。建立socket连接就行了。然后就是页面上要有个js来改变页面的数据。代码大概如下:

 

 

<script>

       var sId = getCookie("JSESSIONID");

   window.onload = function(){

           listener.action = listener.action + "&JSESSIONID="+sId;

           listener.submit();

       }

       function showMsg(msg){

           var msgDiv = document.createElement("div");

           msgDiv.innerHTML = msg.user + " say: " + msg.msg;

           document.all.info.appendChild(msgDiv);

       }

       function getCookie(sName){

           var aCookie = document.cookie.split("; ");

           for (var i=0; i < aCookie.length; i++){

              var aCrumb = aCookie[i].split("=");

              if (sName == aCrumb[0])

                  return unescape(aCrumb[1]);

           }

           return null;

       }

       

</script>

<iframe name="result" width=0 height=0>

       </iframe>

       <iframe name="send">

       </iframe>

       <form method="post" name="listener" target="result"

    action="http://localhost:81/index.jsp?callback=window.parent.showMsg">

    </form>

 

 

注:在这学习的过程中是参照牛人hexiaodong的代码,其blog地址http://hexiaodong.iteye.com/

分享到:
评论
4 楼 only_java 2009-10-22  
likeblood 写道
http协议本身就支持长连接 如果你只用浏览器以http方式连接 不用这么麻烦 看看http协议吧

我不是用浏览器以http方式连接 ,是Tcp链接
3 楼 likeblood 2009-10-22  
http协议本身就支持长连接 如果你只用浏览器以http方式连接 不用这么麻烦 看看http协议吧
2 楼 only_java 2009-10-22  
<div class="quote_title">kevindoudou 写道</div>
<div class="quote_div">
<p>Comet不是长连接技术吗?为什么客户端代码没有轮询呢?<img src="/images/smiles/icon_biggrin.gif" alt=""></p>
<p> </p>
</div>
<p><br>Comet是长连接啊,只要服务端不关闭连接就行了啊</p>
1 楼 kevindoudou 2009-10-21  
<p>Comet不是长连接技术吗?为什么客户端代码没有轮询呢?<img src="/images/smiles/icon_biggrin.gif" alt=""></p>
<p> </p>

相关推荐

    学习笔记 MHT3

    最后,“comet push学习记录 - 企业应用 - Java - JavaEye论坛”提供了更多关于Comet技术在实际项目中的应用案例和经验分享,可以帮助开发者解决在实践中遇到的问题,提升解决问题的能力。 总的来说,这份“学习...

    一个完整的用ajax反转 server push(服务器主动向页面推送数据)技术实现的web聊天室源码

    综上所述,这个Web聊天室项目涵盖了从客户端到服务器端的完整实时通信流程,是学习和实践Ajax反向推送技术的一个好例子。通过深入研究和理解这个源码,开发者可以掌握如何在实际项目中应用Server Push,提高Web应用...

    监视用户的登入登出和页面推送技术

    通过分析和学习这些代码,你可以更好地理解DWR Push的使用方法,以及如何结合jQuery1.5来实现用户登录状态的监控和页面信息的推送。 总结起来,监视用户的登录登出以及页面推送技术是现代Web应用中的重要组成部分,...

    pushlet服务器推送技术

    #### 三、Comet(Ajax Push)简介 Comet,也被称为Ajax Push或Reverse Ajax,是一种允许服务器主动向客户端发送数据的技术。它通过保持TCP连接的长时开放状态,使得服务器能够实时地将数据推送给客户端。这种方式与...

    Flex+BlazeDS+java通信详细笔记和源代码

    Flex+BlazeDS+Java通信是构建富互联网应用程序(RIA)的一种常见技术组合,它允许前端的Flex客户端与后端的Java服务器进行实时双向通信。...而`PushTest6`的源代码则可以作为学习和理解这种通信方式的实践案例。

    day03_JavaScript预习笔记1

    总的来说,这个学习笔记涵盖了JavaScript的基础知识、Ajax编程、jQuery框架以及相关插件的使用,为深入理解和实践JavaScript提供了坚实的基础。无论是前端开发还是全栈开发,掌握这些技能都是非常重要的。

    com4j http推送开源组件

    6. **错误处理与调试**:一个完善的开源组件会考虑错误处理机制,提供日志记录和调试工具,方便开发者诊断和解决问题。 7. **示例与教程**:博客中可能包含使用com4j的示例代码,帮助开发者快速理解如何在实际项目...

    pushlet聊天工具编辑中。。。。

    根据提供的标签“源码”和“工具”,我们可以推断这个压缩包可能包含了一个聊天工具的源代码,用于帮助开发者理解和学习如何构建类似的应用。由于描述中提到的博文链接已失效,无法直接获取详细开发过程,但我可以为...

    [聊天留言]PowerTalkBox 即时通讯源码(改进版)_powertalkbox.zip

    - **推送服务**:为了实现实时性,IM系统通常会使用Apple的APNs(Apple Push Notification service)和Google的FCM(Firebase Cloud Messaging)来向离线用户推送消息。 - **消息队列**:处理高并发下的消息发送,...

    《Jetty6_指南书》

    - **AJAX Push**: 如何使用Jetty实现AJAX Push功能。 - **Comet模式**: 使用Comet模式实现长轮询和服务器推送。 #### 十五、嵌入式Jetty - **如何嵌入**: 将Jetty作为库嵌入到其他Java应用中。 - **应用场景**: ...

    jetty指导书

    - **异步处理**: 通过Continuations机制支持异步Servlet,这对于实现Ajax Push等功能非常重要。 - **高性能IO**: 提供了基于NIO的高效连接器,以提高并发处理能力。 **1.2 Jetty的特点** Jetty相较于其他Web容器...

Global site tag (gtag.js) - Google Analytics