Vaadin 14:在页面刷新时删除广播注册

Vaadin 14:在页面刷新时删除广播注册,vaadin,vaadin-flow,vaadin14,Vaadin,Vaadin Flow,Vaadin14,我按照Vaadin教程()播放事件并注册 Registration eventRegistration; @Override protected void onAttach(AttachEvent attachEvent) { log.debug("In attach..."); UI ui = attachEvent.getUI(); eventRegistration= Broadcaster.register( "ev

我按照Vaadin教程()播放事件并注册

Registration eventRegistration;

@Override
protected void onAttach(AttachEvent attachEvent) {
    log.debug("In attach...");
    UI ui = attachEvent.getUI();
    eventRegistration= Broadcaster.register(
        "eventName", 
        message -> ui.access(() -> {
           log.debug("Request to refresh grid...");
           presenter.refreshGrid();
           ui.push();
        }));
}

@Override
protected void onDetach(DetachEvent detachEvent) {
    log.debug("In detach...");
    if(eventRegistration != null) {
        eventRegistration.remove();
        eventRegistration = null;
    }
}
除了刷新页面时,
ondeach()
中的逻辑未被执行之外,一切都正常。但是,刷新后,您将输入
onAttach()
方法。因此,您实际上要注册几个“相同”的侦听器,而不删除前一个侦听器,并且您实际上会获得双倍的侦听器。例如,仅当您转到另一个菜单项时才能访问
ondeach()
方法

您可以在下面找到一个示例日志。


Vaadin建议在刷新之前/刷新期间删除这些侦听器的方法是什么?

最终应调用
onDetach
方法

关闭或刷新选项卡时,不会向服务器发送任何事件,因此服务器不知道应分离旧UI

这就是他们进来的地方。UI在默认情况下每5分钟发送一次心跳请求,如果服务器注意到旧UI错过了三次心跳,它将被分离。或者,它将在会话到期时分离

换句话说,
onDetach
方法应该在大约20分钟后调用

关闭或刷新选项卡时不向服务器发送事件的原因是,这可能会阻止在处理请求时刷新/关闭选项卡,这是不好的用户体验。此外,这还不包括关闭计算机或断开网络连接的情况


有一种称为Beacon API的东西,可用于在刷新或关闭选项卡时通知服务器,而不会导致浏览器延迟。使用此选项可以立即分离UI。

解决此问题的最简单方法是在添加UI之前检查
eventRegistration
是否为null

@Override
protected void onAttach(AttachEvent attachEvent) {
    log.debug("In attach...");
    UI ui = attachEvent.getUI();
    if (eventRegistration == null) {
       eventRegistration= Broadcaster.register(
          "eventName", 
          message -> ui.access(() -> {
             log.debug("Request to refresh grid...");
             presenter.refreshGrid();
             ui.push();
          }));
    }
}

查看Erik的另一个答案,为什么onDetach的调用被延迟。

我建议使用Unload Beacon插件:或类似的方法,如食谱中所示:-本质上,它是在执行JavaScript代码片段,为Window的
Unload
事件添加一个事件监听器:

ui.getElement().executeJs(
"window.addEventListener('unload', function() {navigator.sendBeacon && navigator.sendBeacon($0)})", relativeBeaconPath);

信标
被发送到自定义的
SynchronizedRequestHandler

,这在我的情况下是不可能的。注册实例“eventRegistration”是视图的类字段(扩展了PolymerTemplate)。所以刷新视图总是会导致一个值为null的注册实例,因此它将导致相同的行为。我明白了,我显然认为您正在使用PreserveOnRefresh,但是是的,您没有声明这一点。