Synchronize sessions with Spring and Guava EventBus

In my current experiments I try to synchronize sessions such that if two users view the same view and one of those makes a change, the other user gets notified via push.

My Spring setup is pretty much as described here: https://vaadin.com/wiki/-/wiki/Main/Spring%20Integration

Push itself is working fine. If I access the UI from a thread started in the
enter()
method of a
View
, the results are immediately visible for the user that opened the view. However, if I access the UI in an event dispatched by Guava’s
EventBus
, it doesn’t work.

The EventBus is a singleton bean:

@Bean public EventBus modelViewEventBus() { return new EventBus("modelView"); } The event publisher is session scoped:

[code]
@Component
@Scope(“session”)
public class ModelViewEventPublisher implements EventPublisher {

@Autowired
private EventBus eventBus;

@Override
public EventBus getEventBus() {
    System.err.println("request for event bus for session " + VaadinSession.getCurrent());
    return eventBus;
}

static class RowAddedEvent {
    Object source;
    // constructor and event data here
}

}
[/code]And the view is prototype scoped:

[code]
@Component
@Scope(“prototype”)
public class ModelView extends VerticalLayout implements View, InitializingBean {

@Autowired
private EventPublisher<RowAddedEvent> modelViewEventBus;

@Override
public void afterPropertiesSet() throws Exception {
    modelViewEventBus.getEventBus().register(this);
}

private void addRow() {
    // triggered from some button
    modelViewEventBus.getEventBus().publish(new RowAddedEvent(this));
}

@Subscribe
public void rowAdded(RowAddedEvent e) {
    if (e.source == this) {
        return;
    }
    UI.getCurrent().access(new Runnable() {
        @Override
        public void run() {
            Notification.show("new row detected, you better update");
        }
    });
}

}
[/code]What I expect is that when I open the view in two browsers and trigger the event in one browser, I get a notification in the other browser. When I add appropriate println statements I can see that events are indeed dispatched. But the notification is not shown. Furthermore, if I reload a few times here and there, sometimes the event even dispatches into the view that posted it. It just doesn’t work. I tried both with
@PreserveOnRefresh
and without, it never worked.

Can anybody help? Am I making some fundamental mistake? How can I communicate between the sessions?

Ok, this was a very stupid mistake. Of course the event listeners run in the same thread as the publisher so
UI.getCurrent()
always refers to the publisher’s UI regardless of the recipient.

So if the recipient is a component,
getUI()
should work (haven’t tried it yet). Otherwise a special event handler can be used that bundles the correct UI and the event target. The latter is a bit messy but it can probably be abstracted away a bit. The result is astonishing.

The explanation above should be sufficient but if someone needs more details, I could whip up some more code.

Danke äh thanks Werner… I had a similar issue (Vaadin7,Guava and Vaadin Push) for a chat component.
After hours of researching, your proposal with getUI() did the trick.
Grüße