精华内容
下载资源
问答
  • Pushlet

    2019-09-27 00:54:34
    在项目中遇到需要实现类似 facebook 消息推送的功能, 也就是服务器端将未读的系统消息条数推送给前台用户(秒级), 即用户在前台页面可以实时的看到最新的系统消息, 经过调研决定使用 Pushlet ...来实现. ...

    在项目中遇到需要实现类似 facebook 消息推送的功能, 也就是服务器端将未读的系统消息条数推送给前台用户(秒级), 即用户在前台页面可以实时的看到最新的系统消息, 经过调研决定使用 Pushlet (http://www.pushlets.com/)  来实现.

          首先, 由于 Pushlet 自己产生的 sessionid 是个随机数, 当后台向前台推送消息时无法和当前登录用户联系起来, 因此我们需要修改 Pushlet 产生 sessionid 的方法. 具体来说就是在

          nl.justobjects.pushlet.core.SessionManager 中修改方法 public Session createSession(Event anEvent) throws PushletException

          修改后的代码为

    1. public Session createSession(Event anEvent) throws PushletException {  
    2.         // Trivial  
    3.         //return Session.create(createSessionId());  
    4.         //return Session.create(createSessionId(), anEvent);  
    5.         return Session.create(anEvent.getField("userid""visitor"));   
    6.     }  

          

           其次, 在前台的 ajax-pushlet-client.js 增加几行代码用来向后台传用户登录 id

          在此代码后面加上

           // Construct base URL for GET
           var url = PL.pushletURL + '?p_event=' + anEvent;

    1. var userid = getMenuValue("userid");  
    2. if (anEvent == 'join' || anEvent == 'join-listen') {    
    3.  url = url + '&userid=' + userid;   
    4. }  

          对 Pushlet 的源代码改造完成, 需要对其重新编译生成 jar 文件后加入到项目 lib 中去

          接下来就是编写 servlet 来获取当前登录用户有多少未读消息

    1. public class NotifyPushletServlet extends HttpServlet{  
    2.     /** 
    3.      *  
    4.      */  
    5.     private static final long serialVersionUID = 1L;  
    6.     private static SystemService systemService;  
    7.   
    8.     public SystemService getSystemService() {  
    9.         return systemService;  
    10.     }  
    11.   
    12.     public void setSystemService(SystemService systemService) {  
    13.         NotifyPushletServlet.systemService = systemService;  
    14.     }  
    15.   
    16.   
    17.     @Override  
    18.     public void init(ServletConfig config) throws ServletException {  
    19.         // TODO Auto-generated method stub  
    20.         super.init(config);  
    21.         ServletContext servletContext = this.getServletContext();    
    22.         WebApplicationContext wac = null;     
    23.         wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);    
    24.         this.setSystemService((SystemService) wac.getBean("systemService"));  
    25.     }  
    26.   
    27.     static public class Pushlet extends EventPullSource {  
    28.         @Override  
    29.         protected long getSleepTime() {  
    30.             return 5000;  
    31.         }  
    32.   
    33.         @Override  
    34.         protected Event pullEvent() {  
    35.             System.out.println(new Date());  
    36.             Event event = Event.createDataEvent("/notifynum");  
    37.             Session[] sessions = SessionManager.getInstance().getSessions();    
    38.             if (sessions.length > 0) {  
    39.                 StringBuilder str = new StringBuilder("");  
    40.                 for (int i = 0; i < sessions.length; i++) {  
    41.                     if (sessions[i].getId().equals("guest")) continue;  
    42.                     if (!str.toString().equals("")) str.append(",");   
    43.                     str.append("'" + sessions[i].getId() + "'");  
    44.                 }  
    45.                 if (!str.toString().equals("")) {  
    46.                     List<?> list = systemService.findNotReadNotificationNumOnline(str.toString());  
    47.                     if (list != null && list.size() > 0) {  
    48.                         Object[] obj = null;  
    49.                         String userid = null, num = null;  
    50.                         for (int i = 0; i < list.size(); i++) {  
    51.                             obj = (Object[]) list.get(i);  
    52.                             userid = obj[0].toString();  
    53.                             num = obj[1].toString();  
    54.                             System.out.println("userid = " + userid + ", num = " + num);  
    55.                             event.setField(userid, num);  
    56.                         }  
    57.                     }  
    58.                 }  
    59.             }  
    60.               
    61.             return event;  
    62.         }  
    63.   
    64.     }  
    65. }  


           最后在前台只接受并显示当前用户自己对应的未读的消息条数

    [javascript] view plaincopyprint?
      1.  <script type="text/javascript">  
      2.     var userid = getMenuValue("userid");  
      3.     PL._init();   
      4. PL.joinListen('/notifynum');  
      5. function onData(event) {   
      6.     var num = event.get(userid);  
      7.     if (num > 0) {  
      8.         document.getElementById('desktopnotify').innerHTML = num;  
      9.         document.getElementById('desktopnotify').style.display='';  
      10.     } else {  
      11.         document.getElementById('desktopnotify').style.display='none';  
      12.     }  
      13. }  
      14. lt;/script>  
      15. 原文:http://blog.csdn.net/dataminer_2007/article/details/7653283

    转载于:https://www.cnblogs.com/eggbucket/archive/2013/01/22/2871591.html

    展开全文
  • pushlet

    2008-04-29 14:40:20
    pushlet开发与应用
  • pushlet

    2009-10-14 17:32:31
    [url]http://www.matrix.org.cn/resource/article/2007-01-16/bcc2c490-a502-11db-8440-755941c7293d.html[/url][quote][size=medium]pushlet是comet的一种实现,而且是开源,其声称能支持目前的web 服务器,于是就...
    该连接对其有比较详细的介绍:
    [url]http://www.matrix.org.cn/resource/article/2007-01-16/bcc2c490-a502-11db-8440-755941c7293d.html[/url][quote][size=medium]pushlet是comet的一种实现,而且是开源,其声称能支持目前的web 服务器,于是就对其提供的服务器端以及客户端代码进行了一番研究,心得如下: 在要使用push的页面中通过执行p_embed()向当前页面添加用来与server通讯的iframe 。后台通讯的页面叫js_pushlet_js.html页面,在这个页面中包含两个frame:一个负责发送请求,也就是controlFrame,一个负责接受请求,即listenFrame。

    clientAdapter的作用:clientAdapter实际上是对response的一个封装,根据向response中write不同的数据,可以分为不同的clientAdapter实现,比如BroswerAdapter就是为了处理浏览器发送的请求。

    在每次打开页面之后都要建立与后台的联系,这个一般都是通过js函数join来实现的,join会调用js_push_client.js中的通用函数(p_join_listen)来做两件事: 第一个就是调用p_join,给用来通讯的iframe赋location.href值,让它去发送请求,接收请求的是 nl.justobjects.pushlet.servlet.Pushlet这个servlet。

    并通过p_event=join告诉后台开始建立连接。在发送完请求之后,后台会response回来一段新的js代码,处理方法是:String nl.justobjects.pushlet.core.BrowserAdapter.event2JavaScript(Event event) throws IOException,里面的返回结果是:" ",后台在处理完join事件之后将结束response。

    push()这个函数在 js_pushlet_net.html这个页面中,不过它还会调用js_pushlet_client.js库中的_push()函数,push函数会根据server传回的参数(这些参数都是一些后台要调用的事件参数),最终我们会根据返回的参数执行相应的回调函数,这些回调函数在事件的应用html 应用页面中实现,比如ping.html页面,回调函数有:onData等。

    第二件事就是调用p_listen再次向后台发送请求(由负责与后台通讯的iframe中另外一个子frame来处理),不过此时需要后台执行的是listen事件,listen跟其他事件不同在于它先找到当前 session对应的订阅者(subscriber),然后调用subscriber的fetchEvent()方法,从订阅者的event queue中取出所有的event对象 ?在js_pushlet_client.js中有一个全局变量:pushletNet这个指的就是用来与后台通信的那个iframe对象,还有一个全局的变量是pushletURI,这个指的是要请求的servlet url。

    后台Event的处理机制:对Event的处理放在EventSource中,EventSource分两种:pull和push,目前主要是pull方式(似乎有些与pushlet矛盾),EventSource有多个实现,这些实现会在source.properties中注册,然后由 EventSourceManager进行管理,EventSource同时会实现Runnable接口,即会用到多线程,在Servlet初始化的时候通过启动EventSourceManager来启动多个EventSource线程。

    由于pushlet采用的是发布/订阅模式,在将Event发送给客户端前,首先要找到所有的客户端对象,这个通过一个pushlet自己定义的session(每一个连接到服务器的客户端会在服务器上注册一个 session来保存客户端信息,在每次发送请求的时候会带有一个sessionid来加以识别)来处理,然后从所有连接的客户端找到订阅了该event 的订阅者,这个是在Dispatcher的multicast()方法中进行的,在订阅者中有一个event queue对象,广播的event对象将保存到该queue中。

    从queue中抓取event的过程则交给controllor完成。 前台需要连续发送请求?不需要,如果需要拼命的发送请求,就不叫comet了,前台只需要发送两个请求,一个是请求连接的join请求事件,一个是对后台进行监听的listen事件,如果后台对应的数据发生了变化,则这个变化会反应到订阅者的event队列中,监听事件请求就是不断的读取订阅者的event队列即可。response需要请求执行完成之后关闭吗?在第一个join事件请求是需要关闭的,listen事件请求则不需要。

    如果客户端连接关闭了,后台如何知晓?在向response中write数据的时候抛出异常,后台就会知道可能是客户端已经关闭,这样该输出将结束 ?pushlet中如何与ajax结合使用?如果使用ajax的话,就是将iframe换成了xmlhttp,后台无变化,就是这么简单![/size][/quote]
    展开全文
  • PushLet

    2013-10-17 10:35:43
    最近一款App需要用到推送技术,简单总结一下使用过程:     两类解决方案:  使用套接口传送信息,需要客户端配置 ... 客户端如何接收,处理信息,如果是Web应用,应该如何结合返回页面并向用户呈现。...

    最近一款App需要用到推送技术,简单总结一下使用过程:

     

     

    两类解决方案:

           使用套接口传送信息,需要客户端配置

           基于HTTP长连接

     

    使用时需要考虑的因素:

           客户端如何接收,处理信息,如果是Web应用,应该如何结合返回页面并向用户呈现。

           客户与服务器端通信的信息格式,采取怎样的出错处理机制。

           Web应用中的浏览器兼容问题

     

    基于客户端套接口的“服务器推”技术简单分类:

     

      传统轮询:修改Html文件头,<META HTTP-RQUIV="Refresh" CONTENT=12>实现浏览器的定时请求(polling)。服务器无需配置,但服务器压力大,带宽损失严重,用户体验度差。

     

       ajax轮询:Ajax定时(通常使用 JavaScript 的 setTimeout 函数)请求增量式的更新,但请求时间间隔设定是一个问题。只需要服务器简单配置,带宽占用不高,但服务器压力没有减少,是较长见的反推技术。

     

       comet:长连接机制 (long lived http)。一次请求后,服务器将挂起请求对像直到有了数据才销毁。它有着较好的性能和实时性,但挂起对象占用了一些服务器资源,也丧失了无状态高并发的特点。

            java appet:在客户端使用 Java Applet ,通过 java.net.Socket java.net.DatagramSocket java.net.MulticastSocket 建立与服务器端的套接口连接,从而实现 服务器推送

     

            使用HTML5的内置WebSocket.或许这是真正的ServerPush,服务器可以主动推数据,每次的请求Header也只有2Byte大小.

            关于WebSocket详解:http://ariesx.iteye.com/blog/1959988

     

     

     

    其它技术:     

            flash xml socket:这种方案实现的基础是:一、 Flash 提供了 XMLSocket 类。二、 JavaScript Flash 的紧密结合:在 JavaScript 可以直接调用 Flash 程序提供的接口。

     

        优点:实时性好(消息延时小);性能好(能支持大量用户)         

     

        缺点:因为 XMLSocket 没有 HTTP 隧道功能, XMLSocket 类不能自动穿过防火墙;

     

               因为是使用套接口,需要设置一个通信端口,防火墙、代理服务器也可能对非 HTTP 通道端口进行限制;

               应用:网络聊天室,网络互动游戏。

     

        

    展开全文
  • pushlet例子

    2018-08-28 16:32:15
    pushlet例子,Pushlet 是一个开源的 Comet 框架,Pushlet 使用了观察者模式:客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话 ID 作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的...
  • pushlet白皮书

    2010-06-01 14:08:11
    pushlet白皮书pushlet白皮书pushlet白皮书pushlet白皮书pushlet白皮书
  • pushlet数据弹窗

    2018-07-20 11:04:36
    pushlet数据弹窗,pushlet数据弹窗,pushlet数据弹窗,pushlet数据弹窗,pushlet数据弹窗
  • pushlet 所需夹包 和配置文件 ajax-pushlet-client.js pushlet-sessionid.jar sources.properties pushlet.properties
  • pushlet 2.03

    2009-01-09 11:49:49
    pushlet 资料 pushlet 资料pushlet 资料pushlet 资料pushlet 资料pushlet 资料pushlet 资料
  • Pushlet详解

    千次阅读 2018-09-28 19:02:04
    Pushlet推送是一种将java后台数据推送到web页面的框架技术。下面我会对Pushlet的定时周期性自动推送、需求推送和点对点推送进行讲解(注意:以下提到的监听路径即事件订阅名)。   首先,需要导入从Pushlet官方...

    Pushlet推送是一种将java后台数据推送到web页面的框架技术。下面我会对Pushlet的定时周期性自动推送、需求推送和点对点推送进行讲解(注意:以下提到的监听路径即事件订阅名)。
     

    首先,需要导入从Pushlet官方下载js文件和jar包,如下图结构。

    图中选中文件为Pushlet相关文件,jquery提供ajax-pushlet-client.js支持。接下来配置web.xml。

    
     
    1. <?xml version="1.0" encoding="UTF-8"?>

    2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">

    3. <welcome-file-list>

    4. <welcome-file>page/index.jsp</welcome-file>

    5. </welcome-file-list>

    6. <servlet>

    7. <servlet-name>pushlet</servlet-name>

    8. <servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class>

    9. <load-on-startup>1</load-on-startup>

    10. </servlet>

    11. <servlet-mapping>

    12. <servlet-name>pushlet</servlet-name>

    13. <url-pattern>/pushlet.srv</url-pattern>

    14. </servlet-mapping>

    15. </web-app>

    由于Pushlet的jajax-pushlet-client.js中获取的项目路径时,是默认当作用户放置ajax-pushlet-client.js在web根目录下的,若放置到其它子目录位置时,在获取web项目路径的时项目路径会加上子目录路径,这样去访问pushlet的java服务时就会找不到。所以,这里我们会改写ajax-pushlet-client.js中的获取web项目路径的方法。
    原始获取web项目路径的方法如下:

    
     
    1. _getWebRoot: function() {

    2. /** Return directory of this relative to document URL. */

    3. if (PL.webRoot != null) {

    4. return PL.webRoot;

    5. }

    6. //derive the baseDir value by looking for the script tag that loaded this file

    7. var head = document.getElementsByTagName('head')[0];

    8. var nodes = head.childNodes;

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

    10. var src = nodes.item(i).src;

    11. if (src) {

    12. var index = src.indexOf("ajax-pushlet-client.js");

    13. if (index >= 0) {

    14. index = src.indexOf("lib");

    15. PL.webRoot = src.substring(0, index);

    16. break;

    17. }

    18. }

    19. }

    20. return PL.webRoot;

    21. },

    改写后获取web项目路径的的方法如下:

    
     
    1. _getWebRoot: function() {

    2. /** Return directory of this relative to document URL. */

    3. if (PL.webRoot != null) {

    4. return PL.webRoot;

    5. }

    6. //derive the baseDir value by looking for the script tag that loaded this file

    7. //获取当前网址,如: http://localhost:8080/PushletNote/index.jsp

    8. var webPath = window.document.location.href;

    9. //获取主机地址之后的目录,如: /PushletNote/index.jsp

    10. var pathName = window.document.location.pathname;

    11. //获取主机地址,如: http://localhost:8080

    12. var hostPaht = webPath.substring(0,webPath.indexOf(pathName));

    13. //获取带"/"的项目名,如:/Pushlet

    14. var projectName = pathName.substring(0,pathName.substr(1).indexOf('/')+1);

    15. PL.webRoot = hostPaht + projectName + "/";

    16. return PL.webRoot;

    17. },

    这样,就可以不必一定要将ajax-pushlet-client.js不放在web根目录下了。
     

    以下三种推送方式的实现都在以上配置的基础上进行。
    index.jsp的代码作用是为了方便统一管理三种方式,代码如下:

    
     
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"

    2. pageEncoding="UTF-8"%>

    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    4. <html>

    5. <head>

    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    7. <title>Pushlet主页</title>

    8. <style type="text/css">

    9. *{

    10. margin:0px auto;

    11. padding:0px;

    12. text-decoration: none;

    13. list-style:none;

    14. font-size:12px;

    15. }

    16. #main{

    17. margin-top:20px;

    18. width:500px;

    19. height:600px;

    20. background:#eee;

    21. border-radius:5px;

    22. padding-left:30px;

    23. padding-top:30px;

    24. }

    25. .list{

    26.  
    27. }

    28. .info{

    29. margin-left:10px;

    30. }

    31. </style>

    32. </head>

    33. <body>

    34. <div id="main">

    35. <div class="list">*<a class="info" href="./page/timing_get_pull.jsp">服务向页面定时周期性推送消息Demo</a></div>

    36. <div class="list">*<a class="info" href="./page/auto_get_pull.jsp">服务按某种需求向页面推送消息Demo</a></div>

    37. <div class="list">*<a class="info" href="./page/one_to_one_get_pull.jsp">一对一推送消息Demo</a></div>

    38. </div>

    39. </body>

    40. </html>

     

    定时周期性推送:

    这种方式是在java代码中配置休眠时间,每隔一定时间向web页面推送一次消息,只要web页面js中配置了启动监听,就能获取相应数据。
    java代码如下:

    
     
    1. package com.pushlet;

    2.  
    3. import nl.justobjects.pushlet.core.Event;

    4. import nl.justobjects.pushlet.core.EventPullSource;

    5.  
    6. /**

    7. * @ProjectName:PushletNote

    8. * @ClassName:PushletHelper

    9. * @author 御兰草

    10. * @email lujiafayx@163.com

    11. * @date 2014年10月10日

    12. * @Description:无

    13. */

    14. public class PushletHelper {

    15. static public class PushletImpl extends EventPullSource{

    16. //定义临时数字静态变量

    17. private int num = 0;

    18.  
    19. /**

    20. * 休眠1秒执行一次pullEvent方法

    21. */

    22. @Override

    23. protected long getSleepTime() {

    24. return 1000;

    25. }

    26.  
    27. /* (non-Javadoc)

    28. * @see nl.justobjects.pushlet.core.EventPullSource#pullEvent()

    29. */

    30. @Override

    31. protected Event pullEvent() {

    32. Event event = Event.createDataEvent("/pushlet/timing");

    33. event.setField("result", num);

    34. num++;

    35. return event;

    36. }

    37.  
    38. }

    39. }

    web页面代码如下(这里我的jsp文件名为timing_get_pull.jsp):

    
     
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"

    2. pageEncoding="UTF-8"%>

    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    4. <html>

    5. <head>

    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    7. <meta http-equiv="Pragma" content="no-cache" />

    8. <title>服务向页面定时周期性推送消息Demo</title>

    9. <script type="text/javascript" src='../js/jquery-1.10.2.js'></script>

    10. <script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>

    11. <script type="text/javascript">

    12. function begin(){

    13. PL._init();

    14. PL.joinListen('/pushlet/timing');

    15. }

    16.  
    17. //Pushlet的js中封装方法,产生消息

    18. function onData(event) {

    19. $("#info").text(event.get("result"));

    20. }

    21.  
    22. function stop(){

    23. //离开

    24. PL.leave();

    25. }

    26. </script>

    27. </head>

    28. <body>

    29. <div style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">

    30. <button onclick="begin();">开始</button>

    31. <a style="text-decoration:none;float:right;font-size:12px;" href="../index.jsp">返回</a>

    32. <center id='info'>显示从后台获取的数据</center>

    33. <button onclick="stop();">停止</button>

    34. <fieldset style="margin-top:30px;padding:0px;width:596px;height:auto;">

    35. <legend>描述</legend>

    36. <p style="text-indent:2em;font-size:12px;">

    37. 这种推送方式,需要在sources.properties中配置重写的EventPullSource类路径。其在程序启动时,后代代码即开始执行,每隔一定时间(getSleepTime方法返回的休眠时间)执行一次pullEvent方法。

    38. js中的Pushlet初始化、监听和停止只能改变去后台获取数据的时间,而不会改变后台Pushlet代码的执行情况。

    39. </p>

    40. </fieldset>

    41. </div>

    42. </body>

    43. </html>timing_get_pull

    接下来要在sources.properties文件中配置java文件的全名:

    
     
    1. #

    2. # Properties file for EventSource objects to be instantiated.

    3. #

    4. # Place this file in the CLASSPATH (e.g. WEB-INF/classes) or directly under WEB-INF.

    5. #

    6. # $Id: sources.properties,v 1.2 2007/11/10 14:12:16 justb Exp $

    7. #

    8. # Each EventSource is defined as <key>=<classname>

    9. # 1. <key> should be unique within this file but may be any name

    10. # 2. <classname> is the full class name

    11. #

    12. #

    13. # Define Pull Sources here. These classes must be derived from

    14. # nl.justobjects.pushlet.core.EventPullSource

    15. # Inner classes are separated with a $ sign from the outer class.

    16.  
    17. # source1=nl.justobjects.pushlet.test.TestEventPullSources$TemperatureEventPullSource

    18. # source2=nl.justobjects.pushlet.test.TestEventPullSources$SystemStatusEventPullSource

    19. # source3=nl.justobjects.pushlet.test.TestEventPullSources$PushletStatusEventPullSource

    20. # source4=nl.justobjects.pushlet.test.TestEventPullSources$AEXStocksEventPullSource

    21. # source5=nl.justobjects.pushlet.test.TestEventPullSources$WebPresentationEventPullSource

    22. # source6=nl.justobjects.pushlet.test.TestEventPullSources$PingEventPullSource

    23.  
    24. source1= com.pushlet.PushletHelper$PushletImpl

    25.  
    26. # TO BE DONE IN NEXT VERSION

    27. # define Push Sources here. These must implement the interface

    28. # nl.justobjects.pushlet.core.EventSource

    29.  

    这样,在页面进行监听就能获取到后台定时推送的消息了。

    按监听路径推送:

    这种方式是在web客户端启动监听后,若java服务在某种需求下向对应监听路径推送消息,web客户端就能获取推送消息。
    java代码如下:

    
     
    1. package com.pushlet;

    2.  
    3. import java.io.IOException;

    4.  
    5. import javax.servlet.ServletException;

    6. import javax.servlet.annotation.WebServlet;

    7. import javax.servlet.http.HttpServlet;

    8. import javax.servlet.http.HttpServletRequest;

    9. import javax.servlet.http.HttpServletResponse;

    10.  
    11. import nl.justobjects.pushlet.core.Dispatcher;

    12. import nl.justobjects.pushlet.core.Event;

    13.  
    14. /**

    15. * Servlet implementation class PushletServlet

    16. */

    17. @WebServlet("/PushletServlet")

    18. public class PushletServlet extends HttpServlet {

    19. private static final long serialVersionUID = 1L;

    20.  
    21. /**

    22. * @see HttpServlet#HttpServlet()

    23. */

    24. public PushletServlet() {

    25. super();

    26. // TODO Auto-generated constructor stub

    27. }

    28.  
    29. /**

    30. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

    31. */

    32. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    33. String str = request.getParameter("count");

    34. if(null != str){

    35. Integer count = Integer.valueOf(str);

    36. Event event = Event.createDataEvent("/pushlet/auto");

    37. event.setField("message", ++count);

    38. //将消息推送到web客户端

    39. Dispatcher.getInstance().multicast(event);

    40. }

    41. }

    42.  
    43. /**

    44. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

    45. */

    46. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    47. doGet(request, response);

    48. }

    49.  
    50. }

    web端代码如下(这里我的jsp文件名为auto_get_pull.jsp):

    
     
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"

    2. pageEncoding="UTF-8"%>

    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    4. <html>

    5. <head>

    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    7. <title>服务按某种需求向页面推送消息Demo</title>

    8. <script type="text/javascript" src='../js/jquery-1.10.2.js'></script>

    9. <script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>

    10. <script type="text/javascript">

    11. //启动监听

    12. function begin(){

    13. PL._init();

    14. PL.joinListen('/pushlet/auto');

    15. }

    16.  
    17. var xhr = new XMLHttpRequest();

    18. //触发服务方法,使其向页面推送消息

    19. function trigger(){

    20. var count = $("#count").text();

    21. var url = PL.webRoot + "PushletServlet?count=" + count;

    22. xhr.open("get", url, true);

    23. xhr.send(null);

    24. }

    25.  
    26. //Pushlet的js中封装方法,产生消息

    27. function onData(event) {

    28. $("#count").text(event.get("message"));

    29. }

    30.  
    31. function stop(){

    32. //离开

    33. PL.leave();

    34. }

    35. </script>

    36. </head>

    37. <body>

    38. <div style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">

    39. <button onclick="begin();">开始监听</button>

    40. <a style="text-decoration:none;float:right;font-size:12px;" href="../index.jsp">返回</a>

    41. <button onclick="trigger();">触发推送</button>

    42. <center id='info'>服务向客户端推送<span id="count" style="color:red;">0</span>次消息</center>

    43. <button onclick="stop();">停监听止</button>

    44. <fieldset style="margin-top:30px;padding:0px;width:596px;height:auto;">

    45. <legend>描述</legend>

    46. <p style="text-indent:2em;font-size:12px;">

    47. 这种推送方式,不需要在sources.properties中配置推送类路径。服务按照指定需求在一定条件向客户端推送消息,客户端开始监听后,若发现有看服务推送的消息,则获取返回。

    48. </p>

    49. </fieldset>

    50. </div>

    51. </body>

    52. </html>

    这样,在web客户端启动监听后,服务端向页面推送消息时web客户端就能接收到了。

    只要保证web客户端的监听路径和服务端推送路径相对应并且具有唯一性,这种方式也能实现点对点消息推送。

    点对点推送:

    这种推送方式是给每个启动监听的web客户端配置一个sessionid,这样就能唯一确定客户端对象,然后在服务上向特定用户推送消息,而相应web客户端再获取相应消息。
    这种推送方式也需要web客户端的监听路径和服务推送路径相一致,并且要重写Pushlet的SessionManager的创建session的方法。重写SessionManager创建session的方法通过继承SessionManger类来实现,代码如下:

    
     
    1. package com.util;

    2.  
    3. import nl.justobjects.pushlet.core.Event;

    4. import nl.justobjects.pushlet.core.Session;

    5. import nl.justobjects.pushlet.core.SessionManager;

    6. import nl.justobjects.pushlet.util.PushletException;

    7.  
    8. public class PushletSessionManager extends SessionManager{

    9.  
    10. @Override

    11. public Session createSession(Event anEvent) throws PushletException {

    12. //Event的getField方法的第二个参数为当传递参数中不存在第一个参数字段时默认使用的值。

    13. return Session.create(anEvent.getField("userId", "visitor"));

    14. }

    15. }

    重写createSession方法完成后,需要将pushlet.properties中SessionManger的配置替换为重写的PushletSessionManger全类名。即:

    sessionmanager.class=com.util.SessionManager

    替换为

    sessionmanager.class=com.util.PushletSessionManager
    

    服务端推送消息java代码如下:

    
     
    1. package com.pushlet;

    2.  
    3. import java.io.IOException;

    4. import java.net.URLEncoder;

    5. import java.text.SimpleDateFormat;

    6. import java.util.Date;

    7.  
    8. import javax.servlet.ServletException;

    9. import javax.servlet.annotation.WebServlet;

    10. import javax.servlet.http.HttpServlet;

    11. import javax.servlet.http.HttpServletRequest;

    12. import javax.servlet.http.HttpServletResponse;

    13.  
    14. import nl.justobjects.pushlet.core.Dispatcher;

    15. import nl.justobjects.pushlet.core.Event;

    16. import nl.justobjects.pushlet.core.SessionManager;

    17.  
    18. /**

    19. * Servlet implementation class OneToOneServlet

    20. */

    21. @WebServlet("/OneToOneServlet")

    22. public class OneToOneServlet extends HttpServlet {

    23. private static final long serialVersionUID = 1L;

    24.  
    25. /**

    26. * @see HttpServlet#HttpServlet()

    27. */

    28. public OneToOneServlet() {

    29. super();

    30. // TODO Auto-generated constructor stub

    31. }

    32.  
    33. private String format(Date date){

    34. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    35. return sdf.format(date);

    36. }

    37.  
    38. /**

    39. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

    40. */

    41. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    42. if(SessionManager.getInstance().hasSession("niko")){

    43. Event event = Event.createDataEvent("/pushlet/onetoone");

    44. //加编码方式解决pushlet不能推送中文问题

    45. event.setField("message", URLEncoder.encode("推送时间:" + format(new Date())));

    46. Dispatcher.getInstance().unicast(event, "niko");//向ID为niko的用户推送

    47. }

    48.  
    49. }

    50.  
    51. /**

    52. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

    53. */

    54. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    55. doGet(request, response);

    56. }

    57.  
    58. }

    web客户端代码如下(这里我的jsp文件名为one_to_one_get_pull.jsp):

    
     
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"

    2. pageEncoding="UTF-8"%>

    3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    4. <html>

    5. <head>

    6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

    7. <title>服务按某种需求向页面推送消息Demo</title>

    8. <script type="text/javascript" src='../js/jquery-1.10.2.js'></script>

    9. <script type="text/javascript" src='../js/ajax-pushlet-client.js'></script>

    10. <script type="text/javascript">

    11. //启动监听

    12. function begin(){

    13. PL.userId ="niko";

    14. PL._init();

    15. PL.joinListen("/pushlet/onetoone");

    16. }

    17.  
    18. var xhr = new XMLHttpRequest();

    19. //触发服务方法,使其向页面推送消息

    20. function trigger(){

    21. var url = PL.webRoot + "OneToOneServlet?";

    22. xhr.open("get", url, true);

    23. xhr.send(null);

    24. }

    25.  
    26. //Pushlet的js中封装方法,产生消息

    27. function onData(event) {

    28. //用decodeURIComponent方法解码

    29. $("#message").text(decodeURIComponent(event.get("message")));

    30. }

    31.  
    32. function stop(){

    33. //离开

    34. PL.leave();

    35. }

    36. </script>

    37. </head>

    38. <body>

    39. <div style="margin:0px auto;width:600px;height:400px;background:#eee;border-radius:5px;">

    40. <button onclick="begin();">开始监听</button>

    41. <a style="text-decoration:none;float:right;font-size:12px;" href="../index.jsp">返回</a>

    42. <button onclick="trigger();">触发推送</button>

    43. <center id='info'>服务向客户端推送为:<span id="message" style="color:red;"></span></center>

    44. <button onclick="stop();">停监听止</button>

    45. <fieldset style="margin-top:30px;padding:0px;width:596px;height:auto;">

    46. <legend>描述</legend>

    47. <p style="text-indent:2em;font-size:12px;">

    48. 点对点推送消息,这种方式需要重写或改写SessionManager类,然后在pushlet.properties配置文件中的sessionmanager.class属性域改写的SessionManger类路径对应,并在pushlet的js中添加userId属性,并添加传递参数的代码。若不在js中添加userId(次要),不重写Session的createSession方法,则默认所有请求、监听都使用默认创建的Session用户visitor。

    49. </p>

    50. <p style="text-indent:2em;font-size:12px;">

    51. PS:pushlet推送消息不能直接推送中文,需要进行转码再推送。通过方法SessionManager.getInstance().hasSession("niko")获取的boolean值反应该用户是否处于监听状态,若用户已在监听,则返回true,若已调用PL.leave()方法,则SessionManager.getInstance().hasSession("niko")的返回值为false。Event的getField方法的第二个参数为当传递参数中不存在第一个参数字段时默认使用的值。

    52. </p>

    53. </fieldset>

    54. </div>

    55. </body>

    56. </html>

    这样,即实现了消息的点对点推送。这里改写SessionManger并配置不会影响前两种推送方式的执行。 --------------------- 本文来自 第三眼的思绪 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/a123638/article/details/40652555?utm_source=copy

    展开全文
  • pushlet测试示例

    2019-02-27 09:54:57
    pushlet源码demo,提供有需要的同学学习,如有更好的实现或建议,欢迎提出
  • pushlet2.0.2

    2008-11-26 12:45:18
    pushlet2.0.2 pushlet2.0.2
  • pushlet-2.0.4

    2017-12-14 16:54:32
    Pushlet 是一个开源的 Comet 框架,Pushlet 使用了观察者模式:客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话 ID 作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。
  • pushlet 例子

    2010-12-22 16:34:47
    pushlet 整合官方网站的例子,在eclipse里面直接导入就可以用了。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,226
精华内容 490
关键字:

Pushlet