I followed the Vaadin tutorial (Creating Collaborative Views) for broadcasting events and register on them.
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;
}
}
Everything works except the fact that when refreshing the page, the logic in the onDetach()
is not executed. After refresh, however, you will enter the onAttach()
method. Because of this you are actually going to register several of 'the same' listeners without removing the previous one and you actually get a doubling of listeners. The onDetach()
method is only accessed if you go to another menu item, for example.
You can find an example log below.
What is the Vaadin recommended way to remove these listeners before/during refresh?
The onDetach
method should be called eventually.
No event is sent to the server when you close or refresh a tab, and as such the server is not aware that the old UI should be detached.
This is where the heartbeat requests come in. The UIs send heartbeat requests every 5 minutes per default, and if the server notices that the old UI has missed three heartbeats, it will be detached. Alternatively, it will be detached when the session expires.
In other words, the onDetach
method should be called after about 20 minutes.
The reason no event is sent to the server when the tab is closed or refreshed is that this could prevent the tab from refreshing/closing while the request is being handled, which is bad user experience. Also, this wouldn't cover the cases where the computer is turned off or the network disconnected.
There is something called the Beacon API that could be used to notify the server when a tab is refreshed or closed without causing a delay in the browser. There is an issue for using this to immediately detach UIs.
I'd recommend using the Unload Beacon add-on: https://vaadin.com/directory/component/unload-beacon-for-vaadin-flow or a similar approach which is demonstrated in the Cookbook: https://cookbook.vaadin.com/notice-closed - essentially, it's executing the JavaScript snippet to add an event listener for Window's unload
event:
ui.getElement().executeJs(
"window.addEventListener('unload', function() {navigator.sendBeacon && navigator.sendBeacon($0)})", relativeBeaconPath);
and the beacon
is sent to a custom SynchronizedRequestHandler
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With