Jsf ManagedBean中的远程轮询和通过推送通知客户端视图
我有一个jsf视图,它在一个表中显示来自托管bean(viewscope)的一些数据,这些数据可以远程检索。Jsf ManagedBean中的远程轮询和通过推送通知客户端视图,jsf,jakarta-ee,timer,Jsf,Jakarta Ee,Timer,我有一个jsf视图,它在一个表中显示来自托管bean(viewscope)的一些数据,这些数据可以远程检索。 当前,使用primefaces轮询组件从客户端视图通过轮询更新数据 这还不够,因为有太多的流量被发送到客户端,现在primefaces支持服务器推送,我只想重新加载数据,并在数据发生更改时将其推送到客户端视图 这应该通过从web层到应用层的轮询来实现,调用类似于hasChanged(…)的方法。如果数据发生更改,web层将向客户端推送通知以重新加载数据 当前客户端轮询 客户端>>web层
当前,使用primefaces轮询组件从客户端视图通过轮询更新数据 这还不够,因为有太多的流量被发送到客户端,现在primefaces支持服务器推送,我只想重新加载数据,并在数据发生更改时将其推送到客户端视图 这应该通过从web层到应用层的轮询来实现,调用类似于
hasChanged(…)
的方法。如果数据发生更改,web层将向客户端推送通知以重新加载数据
当前客户端轮询
客户端>>web层>应用层
客户端通过ajax向web层请求数据,而ajax又向应用层请求数据和更新视图
希望web层轮询和推送
客户端应用层
如果数据已更改,web层将轮询应用层并代表其重新加载,并通知(推送)客户端更新视图
方法:
在web层的托管bean上实现轮询的最佳方法是什么
- 服务器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,我在回答中添加了更多的实现细节。我可能造成了您的混淆,应用层中的对象是