gpt4 book ai didi

jsf - ManagedBean 中的远程轮询并通过推送通知客户端 View

转载 作者:行者123 更新时间:2023-12-04 04:31:16 27 4
gpt4 key购买 nike

我有一个 jsf View ,它显示了来自表中托管 bean( View 范围)的一些数据,这些数据是远程检索的。
目前,数据是通过使用 primefaces 轮询组件从客户端 View 轮询来更新的。

这还不够,因为有太多流量被发送到客户端,而且现在 primefaces 支持服务器推送,我只想重新加载数据并将其推送到客户端 View (如果数据已更改)。

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

当前客户投票

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

客户端通过 ajax 向 web 层请求数据,再次向应用层请求数据并更新 View

希望网络层投票和推送

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

网络层轮询应用层数据是否已更改并代表重新加载并通知(推送)客户端更新 View

方法:

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

  • 托管 bean 中的 TimerTask
    Spawning threads in a JSF managed bean for scheduled tasks using a timer
  • 带有调度注释的附加 EJB
  • 带有 TimerService 的附加 EJB
  • 其他?

  • 编辑:

    架构:(三层)
  • Server1:数据库
  • Server2:应用层(EAR 与远程 EJB + Hibernate)
  • Server3:网络层(使用 JSF 2.0 + Primefaces 3.4 的 WAR)
  • 客户端:浏览器

  • Architecture

    最佳答案

    根据我的经验,我可以推荐两条路线,Spring Integration 和 CDI Events。我推荐 Spring 路线,但根据您当前的堆栈,我认为 CDI events你覆盖了吗?它们干净利落地帮助您实现 Observer/Observable 模式,并且您也可以清晰地分离层。不过我必须警告您,这种方法仅对中小型用例有效。考虑以下:

  • 设计和实现 Event封装所有需要传递给消费者的信息的类。我们称之为 FundsTransfer event 您的事件实现应该包含足够的信息,以使监听器仅过滤感兴趣的事件。
    一个简单的 POJO
    class FundsTransfer {

    BigDecimal transferValue;
    Date transferDate;
    int transferCurrencyCode;

    public FundsTransfer(BigDecimal transferValue, Date date, int currencyCode) {
    //set accordingly
    }
    //setters and getters
    }
  • 在业务层实现一个业务对象,叫它Notifier .轮询的功能应该委托(delegate)给这个对象。它将负责创建和发布 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 作为我的观察者。见 this有关 EJB 计时器的介绍。再次,Observer对象将存在于应用层
  • 每个客户层都可以访问一个监听器对象,当感兴趣的事件发生时将通知该监听器对象(即由 Notifier 类型发布)。然后监听器可以发出 push基于此事件。您的监听器对象可能是带有 @Named 的 POJO CDI 注释。在您的监听器对象中,只需使用 @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)
    ---------------------------------------------------
    | | | | | | | | | | | |

    关于jsf - ManagedBean 中的远程轮询并通过推送通知客户端 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13060337/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com