最近使用pushlet做了一个新消息及时提醒的功能。我使用的框架是Spring + Spring MVC + MyBatis,没有仔细研究其原理,只是简单的将其整合到我的项目中。下面总结一下使用步骤,将来使用的时候也可以再参考一下。
1、从官网下载pushlet的压缩包(版本为:pushlet-2.0.4);
2、将pushlet.jar(目录为:pushlet-2.0.4\lib)拷贝到lib目录下;
3、解压,并将pushlet.properties和sources.properties(目录为:pushlet-2.0.4\webapps\pushlet\WEB-INF\classes\)两个文件拷贝到我们自己项目的WEB-INF目录下。其中pushlet.properties不需要修改,而sources.properties稍后需要根据实际情况调整;
4、在web.xml中加入如下配置:
<servlet> <servlet-name>pushlet</servlet-name> <servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>pushlet</servlet-name> <url-pattern>/pushlet.srv</url-pattern> </servlet-mapping>其中 <url-pattern>/pushlet.srv</url-pattern>使用默认配置。
5、创建一个Controller,里面有一个静态的内部类,需要继承自nl.justobjects.pushlet.core.EventPullSource类。由于,我在页面中弹出的提醒消息需要通过数据库获取,所以,在Controller中需要有相关的参数。具体代码如下:
package com.sinowel.ucp.multimessage.controller; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import com.sinowel.ucp.multimessage.domain.MultiMessage; import com.sinowel.ucp.multimessage.service.AbstractMultiMessageService; import nl.justobjects.pushlet.core.Event; import nl.justobjects.pushlet.core.EventPullSource; /** * 类描述: 新消息提醒控制器 修改历史: * * @author weina * @date 2014-1-12 上午10:11:12 * @description 其它: */ @Controller public class PendingMessageTipController { private static final Logger logger = LoggerFactory.getLogger(PendingMessageTipController.class); private static AbstractMultiMessageService mulitMessageService; public static AbstractMultiMessageService getMulitMessageService() { return mulitMessageService; } @Autowired public void setMulitMessageService( AbstractMultiMessageService mulitMessageService1) { mulitMessageService = mulitMessageService1; } static public class PendingMessageTipPlushlet extends EventPullSource { // 休眠10秒 @Override protected long getSleepTime() { return 10000; } @Override protected Event pullEvent() { Event event = Event.createDataEvent("/getNewMessage"); MultiMessage multiMessage = new MultiMessage(); multiMessage.setDestAgentId("admin"); multiMessage.setStatus("0"); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); try { String tipMessage = ""; // 此处省略业务代码 // …… event.setField("message", new String(tipMessage.getBytes("UTF-8"), "ISO-8859-1")); } catch (Exception e) { if (logger.isDebugEnabled()) e.printStackTrace(); logger.info(e.toString()); } return event; } } }
6、修改sources.properties文件,将source1修改为:
source1=com.sinowel.ucp.multimessage.controller.PendingMessageTipController$PendingMessageTipPlushlet其他的source全部删除掉。
7、将ajax-pushlet-client.js引入文本项目,如WebContent\js\;
8、在需要弹出消息窗口的页面引人ajax-pushlet-client.js文件;此处需要说明一下,使用前在网上也查找过一下资料,可以参考http://cuisuqiang.iteye.com/blog/1416771。首先修改_getWebRoot函数:
// index = src.indexOf("lib"); index = src.indexOf("js");
但是都不能实现我需要的功能——在非WebContent\index.jsp页面弹出提示窗口,而是在WebContent\WEB-INF\view\jsp\XXX\XXX.jsp页面上弹出提示窗口(这个是我的web项目的首页)。使用网上的资料时,在WebContent根目录下的jsp页面中可以实现很轻松的实现弹出窗口效果。但是在我的WebContent\WEB-INF\view\jsp\XXX\XXX.jsp页面,一直不出现。最后查看了一下ajax-pushlet-client.js的源码。发现_onEvent方法中有如下内容:
if (eventType == 'data') { PL._setStatus('data'); PL._doCallback(event, window.onData); }我使用的eventType是data类型的,所以其他的没关注。发现它回调的函数是 window.onData。而我的 WebContent\WEB-INF\view\jsp\XXX\XXX.jsp页面上的 onData函数
PL._init(); PL.joinListen('/getNewMessage'); function onData(event) { showMessage(event.get("message")); }却一直无法调用。所以,我修改了 ajax-pushlet-client.js的源码:增加一个 fun变量用来保存要执行的自定义函数,增加 setFun和 getFun两个函数分别用来设置和获取自定义函数。具体内容如下:
var PL = { NV_P_FORMAT: 'p_format=xml-strict', NV_P_MODE: 'p_mode=pull', pushletURL: null, webRoot: null, sessionId: null, // add by weina begin fun : null, // add by weina end // …… state: 1, /************** START PUBLIC FUNCTIONS **************/ // add by weina begin setFun : function(funName) { fun = funName; }, getFun : function () { return fun; }, // add by weina end // ……_onEvent函数修改内容如下: