Pushlet 推送数据库消息到前台指定用户

来源:互联网 发布:网络信息安全系统 编辑:程序博客网 时间:2024/05/16 14:12

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

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

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

      修改后的代码为

public Session createSession(Event anEvent) throws PushletException {// Trivial//return Session.create(createSessionId());//return Session.create(createSessionId(), anEvent);return Session.create(anEvent.getField("userid", "visitor")); }

      

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

      在此代码后面加上

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

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

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

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

public class NotifyPushletServlet extends HttpServlet{/** *  */private static final long serialVersionUID = 1L;private static SystemService systemService;public SystemService getSystemService() {return systemService;}public void setSystemService(SystemService systemService) {NotifyPushletServlet.systemService = systemService;}@Overridepublic void init(ServletConfig config) throws ServletException {// TODO Auto-generated method stubsuper.init(config);ServletContext servletContext = this.getServletContext();  WebApplicationContext wac = null;   wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);  this.setSystemService((SystemService) wac.getBean("systemService"));}static public class Pushlet extends EventPullSource {@Overrideprotected long getSleepTime() {return 5000;}@Overrideprotected Event pullEvent() {System.out.println(new Date());Event event = Event.createDataEvent("/notifynum");Session[] sessions = SessionManager.getInstance().getSessions();  if (sessions.length > 0) {StringBuilder str = new StringBuilder("");for (int i = 0; i < sessions.length; i++) {if (sessions[i].getId().equals("guest")) continue;if (!str.toString().equals("")) str.append(","); str.append("'" + sessions[i].getId() + "'");}if (!str.toString().equals("")) {List<?> list = systemService.findNotReadNotificationNumOnline(str.toString());if (list != null && list.size() > 0) {Object[] obj = null;String userid = null, num = null;for (int i = 0; i < list.size(); i++) {obj = (Object[]) list.get(i);userid = obj[0].toString();num = obj[1].toString();System.out.println("userid = " + userid + ", num = " + num);event.setField(userid, num);}}}}return event;}}}


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

   <script type="text/javascript">    var userid = getMenuValue("userid"); PL._init(); PL.joinListen('/notifynum');function onData(event) { var num = event.get(userid);if (num > 0) {document.getElementById('desktopnotify').innerHTML = num;document.getElementById('desktopnotify').style.display='';} else {document.getElementById('desktopnotify').style.display='none';}}</script>


     

原创粉丝点击