Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf ManagedBean中的远程轮询和通过推送通知客户端视图_Jsf_Jakarta Ee_Timer - Fatal编程技术网

Jsf ManagedBean中的远程轮询和通过推送通知客户端视图

Jsf ManagedBean中的远程轮询和通过推送通知客户端视图,jsf,jakarta-ee,timer,Jsf,Jakarta Ee,Timer,我有一个jsf视图,它在一个表中显示来自托管bean(viewscope)的一些数据,这些数据可以远程检索。 当前,使用primefaces轮询组件从客户端视图通过轮询更新数据 这还不够,因为有太多的流量被发送到客户端,现在primefaces支持服务器推送,我只想重新加载数据,并在数据发生更改时将其推送到客户端视图 这应该通过从web层到应用层的轮询来实现,调用类似于hasChanged(…)的方法。如果数据发生更改,web层将向客户端推送通知以重新加载数据 当前客户端轮询 客户端>>web层

我有一个jsf视图,它在一个表中显示来自托管bean(viewscope)的一些数据,这些数据可以远程检索。
当前,使用primefaces轮询组件从客户端视图通过轮询更新数据

这还不够,因为有太多的流量被发送到客户端,现在primefaces支持服务器推送,我只想重新加载数据,并在数据发生更改时将其推送到客户端视图

这应该通过从web层到应用层的轮询来实现,调用类似于
hasChanged(…)
的方法。如果数据发生更改,web层将向客户端推送通知以重新加载数据

当前客户端轮询

客户端>>web层>应用层

客户端通过ajax向web层请求数据,而ajax又向应用层请求数据和更新视图

希望web层轮询和推送

客户端应用层

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

方法:

在web层的托管bean上实现轮询的最佳方法是什么

  • 托管bean中的TimerTask
  • 带有计划注释的附加EJB
  • 带有TimerService的附加EJB
  • 其他的
  • 编辑:

    体系结构:(3层)

    • 服务器1:数据库
    • 服务器2:应用层(带远程EJB+Hibernate的EAR)
    • Server3:web层(与JSF2.0+Primefaces 3.4的战争)
    • 客户端:浏览器

    根据我的经验,我可以推荐两条路线,Spring集成和CDI活动。我建议您选择春季路线,但根据您目前的情况,我想您已经介绍过了。它们干净地帮助您实现观察者/可观察模式,您也可以实现层次的干净分离。但我必须警告您,这种方法只对中小型用例有效。考虑以下事项:

  • 设计并实现一个
    事件
    类,该类封装了需要传递给消费者的所有信息。让我们称之为
    FundsTransfer
    事件您的事件实现应该包含足够的信息,以便侦听器仅对感兴趣的事件进行筛选。 简单的POJO

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

    //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作为观察者。有关EJB计时器的介绍,请参阅。同样,
    Observer
    对象将位于应用层中

  • 客户端层将分别访问一个侦听器对象,该对象将在感兴趣的事件发生时得到通知(该事件已由
    通知程序发布)。然后,侦听器可以基于此事件发出一个
    推送
    。您的侦听器对象可以是带有
    @命名的
    CDI注释的POJO。在侦听器对象中,只需使用
    @Observes
    注释实现一个方法,并使用侦听器感兴趣的事件类型的参数:

    public void onNewTransfer(@Observes FundsTransfer transfer) {
        if (transfer.compareTo(new BigDecimal("150000")) > 0) {
            //push to view.
        }
    }
    
    与CDI提供的消息过滤选项相比,上述过滤仍然相当粗糙。正如我前面提到的教程所示,您可以创建CDI限定符,以便对消息进行更细粒度的过滤。正如我前面所说的,这对于大规模部署来说有点沉重,在这种情况下,如果您需要依赖spring,我建议您选择spring集成路线

  • 总之,该系统的模型将为:

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

    我认为,在许多位置上,您不希望推送实际数据进行更新,只是通知客户机应请求对页面的某些部分进行部分更新。这样可以避免在通道上实现安全性。此外,您还可以执行从ejb层直接驱动到comet/atmosphere的推送事件。不,我不想推送实际数据,只是按照您的建议发送通知。你是说从驻留在web层上的ejb?我在ejb层中推送ejb。(将大气依赖项添加到ejb.jar)。请看:我不知道您所说的ejb层是什么意思。我有一个三层架构,带有EAR和WAR。当您使用ejb层时,您是指应用层(EAR)吗?也许我使用了错误的术语。我考虑存档您打包的应用程序的不同工件。webtier进入.war ejb,实体进入ejb.jar,然后两者都进入.ear这个观察者模式在两个不同的服务器应用层和web层(远程观察者模式)之间工作吗<代码>在业务层实现业务对象,称之为Notifier。轮询功能应委托给此对象。
    我最初的问题是如何解决轮询问题?我有点困惑或者没有足够的经验回答您的问题。@djmj,
    通知程序
    对象将位于应用层。它应该进行轮询/检查更改。根据调查结果,它将在整个JEE环境中广播一条信息。
    观察者
    对象将根据
    通知者的广播接收一个
    事件
    实例/通知。
    Observer
    对象将位于web层,并且基于
    事件
    实例,您可以使用primefaces推送在客户端实现更改。@djmj,我在回答中添加了更多的实现细节。我可能造成了您的混淆,应用层中的对象是