在ManagedBean中进行远程轮询,并通过push通知客户端视图 [英] Remote polling in ManagedBean and notify client-view via push

查看:130
本文介绍了在ManagedBean中进行远程轮询,并通过push通知客户端视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个jsf视图,它显示了远程检索的表中托管bean(viewscope)的一些数据。

目前通过使用primefaces从客户端视图轮询来更新数据poll group。



这还不够,因为要向客户端发送大量流量,现在primefaces支持服务器推送我只想重新加载数据并推送它如果数据已更改,则访问客户端视图。



这应该通过从Web层到应用层的轮询来实现,调用类似 hasChanged(...)。如果数据发生变化,网络层会向客户推送通知以重新加载数据。



当前客户投票



客户>> 网络层>> 应用层



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



希望进行网络层轮询和推送



客户<< 网络层>> app-tier



web-tier polls app-tier如果数据已更改并代表重新加载并通知(推送)客户端更新视图



方法:



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


  1. 托管bean中的TimerTask

    你有没有报道过它们干净地帮助您实现Observer / Observable模式,您也可以实现层次的清晰分离。我必须警告你,这种方法仅对中小用例有效。请考虑以下事项:


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

        class FundsTransfer {

      BigDecimal transferValue;
      日期transferDate;
      int transferCurrencyCode;

      public FundsTransfer(BigDecimal transferValue,Date date,int currencyCode){
      //相应地设置
      }
      // setters and getters
      }


    2. 在业务层实施业务对象,将其称为通知程序。应将轮询功能委托给此对象。它将负责创建和发布事件类型的对象,以响应服务器端的更改。根据您的要求,此对象可以是处理所有事件类型的单例,也可以是一组通知程序类型轮询不同的事件。

        // Observer对象的示例实现:
      @Singleton //定义一个singleton EJB
      public class PollerService {

      @Inject
      Event fundsTranferNotifier;

      //此注释指定轮询方法应每秒运行一次。
      @Schedule(second =* / 1,minute =*,hour =*,persistent = false)
      public void pollIt(){
      boolean found = this。 pollingMethod(); // pollingMethod()将执行实际轮询
      if(found){//基于轮询方法的结果,触发通知方法
      blowWhistleOnTransfer();
      }
      }

      public void blowWhistleOnTransfer(){
      //这是广播事件。
      fundsTransferNotifier.fire(new FundsTransfer(new BigDecimal(100000,new Date(),855));
      }
      }

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


    3. 客户层将分别具有访问权限当感兴趣的事件发生时(通过 Notifier 类型发布)将通知的侦听器对象。然后侦听器可以发出基于此事件推送。您的侦听器对象可以是带有 @Named CDI注释的POJO。在您的侦听器对象中,只需实现一个方法 @Observes 注释,其中包含侦听器感兴趣的事件类型的参数:

        public void onNe wTransfer(@Observes FundsTransfer transfer){
      if(transfer.compareTo(new BigDecimal(150000))> 0){
      //推送查看。
      }
      }

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


    总之,系统的模型将是:

     一个Poller(通知程序)对象(在应用程序层中)
    |
    |
    |
    多个侦听器对象(在Web层中)
    --------------------------------- ------------------
    | | | | | | | | | | | |


    I have a jsf view which shows some data from a managed-bean (viewscope) in a table, that is retrieved remotely.
    Currently the data is updated via polling from the client-view using primefaces poll component.

    This is not sufficient enough, since to much traffic is sent to client and now that primefaces supports server-push I only want to reload the data and push it to the client-view if data has been changed.

    This should be realized via polling from the web-tier to application tier calling a method like hasChanged(...). If data is changed the web-tier pushes a notification to client to reload data.

    Current client poll

    client >> web-tier >> app-tier

    client asks web-tier via ajax for data which again asks app-tier for data and updates view

    Wished web-tier poll and push

    client << web-tier >> app-tier

    web-tier polls app-tier if data has changed and reloads on behalf and informs (pushes) client to update view

    Approaches:

    What is the best approach to realize the polling at the managed-bean in the web-tier?

    1. TimerTask in the managed-bean
      Spawning threads in a JSF managed bean for scheduled tasks using a timer
    2. Additional EJB with Schedule annotation
    3. Additional EJB with TimerService
    4. other?

    Edit:

    Architecture: (3-tier)

    • Server1: database
    • Server2: app-tier (EAR with Remote EJB + Hibernate)
    • Server3: web-tier (WAR with JSF 2.0 + Primefaces 3.4)
    • Client: Browser

    解决方案

    Based on my experience, I can recommend two routes, Spring Integration and CDI Events. I'd recommend the Spring route, but based on your current stack, I think CDI events have you covered. They cleanly help you achieve the Observer/Observable pattern and you can pull of a clean separation of tiers too. I must warn you though, this approach is effective only for a small-medium use case. Consider the following:

    1. Design and implement an Event class that encapsulates all the information that is required to be delivered to consumers. Let's call it a FundsTransfer event Your event implementation should contain enough information to enable listeners filter only for events of interest. A simple POJO

      class FundsTransfer {
      
          BigDecimal transferValue;
          Date transferDate;
          int transferCurrencyCode;
      
          public FundsTransfer(BigDecimal transferValue, Date date, int currencyCode) {
              //set accordingly
          }
          //setters and getters
      }
      

    2. Implement a business object at the business layer, call it Notifier. The function of polling should be delegated to this object. It will be in charge of creating and publishing objects of type event in response to changes on the server side. Depending on your requirements, this object could be a singleton to handle all Event types or you could have a group of Notifier types polling for different events.

      //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));
          }
      }
      

      In the code above, I've used a Timer EJB as my Observer. See this for an introduction to EJB timers. Again, the Observer object will live in the app tier

    3. The client tier will each have access to an listener object that will be notified when an event of interest occurs (that is has been published by a Notifier type). Then the listener can issue a push based on this event. Your listener object could be a POJO with @Named CDI annotation. In your listener object, simply implement a method with an @Observes annotation, with a parameter of the type of event the listener is interested in:

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

      The above filtering is still quite crude compared to the message filtering options that CDI provides. As you can see from the tutorial I referenced earlier, you could create CDI qualifiers that can give you finer grained filtering on messages. Like I stated earlier, this is a bit heavy for large scale deployment, in which case I'd advise the spring integration route, if you're up to take the dependency on.

    In summary, the model of the system will be:

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

    这篇关于在ManagedBean中进行远程轮询,并通过push通知客户端视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆