Pushlet如何使用以及实现后台信息的推送

可以通过Pushlet来实现服务器对多个在线页面的时时提醒。Pushlet 是一个开源的 Comet 框架,Pushlet 使用了观察者模式:客户端发送请求,订阅感兴趣的事件;服务器端为每个客户端分配一个会话 ID 作为标记,事件源会把新产生的事件以多播的方式发送到订阅者的事件队列里。观察者模式的基本概念是:观察者模式完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

下面我们介绍一个在具有审批和调查的系统中,当审批人回退到调查时,如果该调查人在线,那么就在他的页面提示带有超链接的信息。难点有两个,一是每间隔一段时间比如5分钟去提示一遍;二是要根据不同的登录用户去提示不同的信息。第一个问题通过Pushlet可以很好的实现,第二个问题是后台如何能根据不同用户登录的ID去发送各自的信息呢,其实这个问题很简单,不需要考虑那么复杂,我在后台代码中把所要提示的所有的ID的信息全部都push到一个集合map中,那么是不是就可以更具用户登录时的ID对比map中的key值,一样即发送与之对应的信息呢,这样难点就全部有了思路,具体我们看代码。

下载最新版本的Pushlet。MyEclipse下建立一个web工程,我这里叫PushletTest,将pushlet.jar加入引用路径,pushlet.properties和sources.properties放入WebRoot/WEB-INF下,sources.properties中配置后台java代码的入口一般是controller类。如图所示:

在web.xml中添加pushlet的servlet的声明,让这个servlet在服务器启动时就启动(load-on-startup为正数),web.xml代码如下:

    <servlet>  
       <servlet-name>pushlet</servlet-name>  
       <servlet-class>nl.justobjects.pushlet.servlet.Pushlet</servlet-class>  
       <load-on-startup>1</load-on-startup>  
     </servlet>  
     <servlet-mapping>  
       <servlet-name>pushlet</servlet-name>  
       <url-pattern>/pushlet.srv</url-pattern>  
     </servlet-mapping> 
然后controller类如下

@Controller
public class ReinvestigatingPushlet extends EventPullSource implements Serializable {  
    private static final long serialVersionUID = -4378845831200885879L;  
    private static ApplicationContext applicationContext;
    private static PushletService pushletService;
    /**
     * 推送时间间隔
     */  
    protected long getSleepTime() {  
        return 300000;  
    }  
    public static void initApplicationContext(){  
        applicationContext=ContextLoaderListener.getCurrentWebApplicationContext();  
    }  
    /** 通过泛型方法取得bean实例 */  
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name){  
        if(applicationContext==null){  
            initApplicationContext();  
        }  
        return (T) applicationContext.getBean(name);  
    }
    /**
     * 推送时所触发的方法
     */ 
    protected Event pullEvent() {  
        //创建事件,并制定事件的主题  
        Event event = Event.createDataEvent("/ynb/helloworld");   //每一个观察者对应一个主题,也就是说你可以同时监视多个事件,在jsp中也会写入该主题的
        String data = "";  
        try {
            pushletService=(PushletService)getBean("pushletServiceImpl");    //此处,其实仅仅是想使用service,但是通过正常的注入是无法实现的,所以通过此方法注入service
            List userList=pushletService.getExamenPersonId();
            System.out.println("有重新调查进件的征信人员---------------:"+userList);
            if(null!=userList&&userList.size()>0){
                for (int i = 0; i < userList.size(); i++) {
                    List<ReinvestigatingApply> reinvestigatingApplyList = pushletService
                    .getReinvestigatingApply(userList.get(i)+"");
                    if(null!=reinvestigatingApplyList&&reinvestigatingApplyList.size()>0){
                        for (int j = 0; j < reinvestigatingApplyList.size(); j++) {
                            ReinvestigatingApply rgApply=reinvestigatingApplyList.get(j);
                            String bussinessContent="申请编号:"+rgApply.getApplicationId()+",打回重新调查的原因:"+rgApply.getBussinessContent()+"。<br/>是否立即处理?";
                            if(j==reinvestigatingApplyList.size()-1){
                                data=data+"<a οnclick='tanchu(\""+bussinessContent+"\","+rgApply.getApplicationId()+","+rgApply.getExamenId()+")'>申请编号<font color='red'>"+rgApply.getApplicationId()+"</font>于"+rgApply.getOptDate()+"被"+rgApply.getOperatorName()+"打回重新调查,请及时处理!</a>";
                                data=new String(data.getBytes("UTF-8"),"ISO-8859-1");
                                event.setField("message"+userList.get(i), data);
                                data="";
                            }else{
                                data=data+"<a οnclick='tanchu(\""+bussinessContent+"\","+rgApply.getApplicationId()+","+rgApply.getExamenId()+")'>申请编号<font color='red'>"+rgApply.getApplicationId()+"</font>于"+rgApply.getOptDate()+"被"+rgApply.getOperatorName()+"打回重新调查,请及时处理!</a><br/>";
                            }
                        }
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
        return event;  
    }  

这样每隔5分钟此controller就会执行一遍

ajax-pushlet-client.js 这个是需要引入的js,找到PL.pushletURL = PL._getWebRoot() + 'pushlet.srv'; PL._getWebRoot()这个加不加具体看你自己项目的目录。

下面就是jsp页面了,如果你想要做提醒,那么最好这个页面就在主页面中写

在index.jsp中首先引入js <script type="text/javascript" src="<%=basePath%>scripts/ajax-pushlet-client.js"></script>

初始化dialog    

$('#chongxindiaochaDialog').dialog( {
        closed : true,
        closable:false,
        buttons : [{
            text : '是',
            iconCls : 'icon-undo',
            handler : function() {
                $('#chongxindiaochaDialog').dialog('close');
                openBorrow();
            }
        } , {
            text : '否',
            iconCls : 'icon-no',
            handler : function() {
                $('#chongxindiaochaDialog').dialog('close');
            }
        } ]
    });

        //重新调查实时提醒
        //PL._init();    这个加上的话有些浏览器不支持,不加的话也可以使用的
        //PL.setDebug(true);
        PL.joinListen("/ynb/helloworld");//监听该主题的事件,如果发生该主题的事件,那么onData()方法会被调用
        function onData(event){
            var content=event.get("message"+<%=SpringSecurityUtils.getCurrentUser().getUserId()%>);
            if(content!=""&&null!=content){
                    $.messager.show({
                           title:'注意啦',
                           width:300,
                           height:150,
                           msg:content,
                           timeout:60000,
                           showType:'slide'
                        });
            }
        }

网上大部分人说是要修改pushlet的java源代码,找到nl.justobjects.pushlet.core包下的SessionManager类,将它的createSession方法改成:

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

但是我做的时候并没有去修改,具体的各位在做的时候可以测试调整,我这边主要就是给一个思路。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值