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
posted @ 2013-01-22 16:20  eggbucket  阅读(546)  评论(0编辑  收藏  举报