繁体   English   中英

在ManagedBean中进行远程轮询,并通过push通知客户端视图

[英]Remote polling in ManagedBean and notify client-view via push

我有一个jsf视图,它显示了远程检索的表中托管bean(viewscope)的一些数据。
目前,使用primefaces poll组件通过客户端视图轮询更新数据。

这还不够,因为要向客户端发送大量流量,现在Primefaces支持服务器推送我只想重新加载数据并在数据发生变化时将其推送到客户端视图。

这应该通过从web层到应用层的轮询来实现,调用像hasChanged(...)这样的方法。 如果数据已更改,则Web层会将通知推送到客户端以重新加载数据。

当前的客户投票

客户端>> web-tier >> app-tier

客户端通过ajax向web层询问数据,该数据再次向app-tier请求数据和更新视图

希望网络层轮询和推送

客户端<< web-tier >> app-tier

如果数据已更改并代表重新加载并通知(推送)客户端更新视图,则web-tier轮询应用层

处理办法:

在Web层中实现托管bean轮询的最佳方法是什么?

  1. 托管bean中的TimerTask
    使用计时器在JSF托管bean中为计划任务生成线程
  2. 带有Schedule注释的附加EJB
  3. 使用TimerService的附加EJB
  4. 其他?

编辑:

架构:(3层)

  • Server1:数据库
  • Server2:app-tier(带远程EJB + Hibernate的EAR)
  • Server3:web-tier(带有JSF 2.0 + Primefaces 3.4的WAR)
  • 客户端:浏览器

建筑

根据我的经验,我可以推荐两个路径,Spring Integration和CDI Events。 我建议使用Spring路由,但根据您当前的堆栈,我认为CDI事件可以覆盖您。 它们干净地帮助您实现Observer / Observable模式,您也可以实现层的清晰分离。 我必须警告你,这种方法仅对中小用例有效。 考虑以下:

  1. 设计并实现一个Event类,该类封装了向消费者提供的所有信息。 我们称之为FundsTransfer事件。您的事件实现应包含足够的信息,以使侦听器仅针对感兴趣的事件进行过滤。 一个简单的POJO

     class FundsTransfer { BigDecimal transferValue; Date transferDate; int transferCurrencyCode; public FundsTransfer(BigDecimal transferValue, Date date, int currencyCode) { //set accordingly } //setters and getters } 
  2. 在业务层实现业务对象,将其称为Notifier 应将轮询功能委托给此对象。 它将负责创建和发布类型event对象以响应服务器端的更改。 根据您的要求,此对象可以是处理所有Event类型的单例,也可以为一组Notifier类型轮询不同的事件。

     //A sample implementation of your Observer object : @Singleton //Defines a singleton EJB public class PollerService { @Inject Event fundsTranferNotifier; //this annotation specifies that the polling method should run every second. @Schedule(second = "*/1", minute = "*", hour = "*", persistent = false) public void pollIt() { boolean found = this.pollingMethod(); // pollingMethod() will do the actual polling if (found) { //based on the outcome of the polling method, fire the notifier method blowWhistleOnTransfer(); } } public void blowWhistleOnTransfer() { //this is the broadcast event. fundsTransferNotifier.fire(new FundsTransfer(new BigDecimal("100000", new Date(), 855)); } } 

    在上面的代码中,我使用了Timer EJB作为我的Observer。 对介绍EJB计时器。 同样, Observer对象将存在于应用层中

  3. 每个客户端层都可以访问一个侦听器对象,该对象将在感兴趣的事件发生时通知(即已通过Notifier类型发布)。 然后,侦听器可以基于此事件发出push 您的侦听器对象可以是带有@Named CDI注释的POJO。 在您的侦听器对象中,只需使用@Observes注释实现一个方法,该方法具有侦听器感兴趣的事件类型的参数:

     public void onNewTransfer(@Observes FundsTransfer transfer) { if (transfer.compareTo(new BigDecimal("150000")) > 0) { //push to view. } } 

    与CDI提供的消息过滤选项相比,上述过滤仍然非常粗糙。 正如您在前面引用的教程中所看到的,您可以创建CDI限定符,以便对消息进行更精细的过滤。 就像我之前所说的那样,对于大规模部署来说,这有点重,在这种情况下,如果您要依赖它,我会建议Spring集成路径。

总之,系统的模型将是:

            One Poller(Notifier) Object (In the app layer)
                    |
                    |
                    |
            Multiple Listener Objects (In the web tier)
---------------------------------------------------
|   |    |    |    |   |   |     |   |    |    |  |  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM