PUSH broadcasts only to single listener among many registered

I have a Vaadin 7.1.2 application with PUSH enabled.

The system uses the broadcast mechanism discussed in the book of vaadin
HERE (11.16.4)
.

If I start up the app in several browsers, I see that each UI is correctly registering itself has a Broadcast Listener. However, when a broadcast message is sent, the listeners are traversed and the appropriate receiveBroadcast method is invoked. The individual listeners are unique.

The problem is that ALL messages appear to go to a single receiver. In other words, none of the other registered clients get a message from the Broadcaster.

Q: Any suggestions?

The issue discussed here may be similar to
this
other issue.

Instead of using static methods on the Broadcaster , have you tried using a EJB Singleton ?
Not sure what application server you are using, but it might not be wise to rely on a Class ( Singleton pattern ) like that.

Also you could try JMS messages for the broadcasting mechanism as in this sample
https://github.com/R2R/CDIChat/

Hi Petrus, I converted the Broadcaster to Singleton (not EJB Singleton) but still same result. (btw, I am using Tomcat 7)

Then I converted to a Spring Service (a Singleton). Again, same behavior. Multiple browsers, different user accounts (logins), but only the first registered client gets the broadcasts.

Who is the ‘PUSH’ expert at Vaadin? Maybe they can let us know if this is a known problem…or operator error :-).

It was
Operator Error
(blush).

The key was locking the session in the receiver method.


public void receiveChat(final ChatPayload chatPayload) {
    // Must lock the session to execute logic safely
    [b]
access(new Runnable() {
[/b]
    @Override
    public void run() {
        // Show it somehow
        ....
    }
});

Petrus, thanks for your help.

Glad you found the problem :slight_smile: .

Hi all,

i have the same problem and this is what my code looks like:

[code]
@Override
public void receiveBroadcast(final String message) {
UI.getCurrent().access(new Thread() {

         @Override
         public void run() {
             addValue(message);
             UI.getCurrent().push();
         }
     });

}
[/code]I have a TextArea, which implements the BroadcastListner from the example. Even though I’m using the access-Method, it still only broadcast to the first registered listener inside the static list.
Anyone can help here?

For your information, I have Push set to manually.

Greetings

Ok, thanks to this
https://vaadin.com/forum#!/thread/3667892
I solved my problem the following way:

[code]
@Override
public void receiveBroadcast(final UI ui, final String message) {
ui.access(new Runnable() {

    @Override
    public void run() {
          addValue(message);
          ui.push();
    }
});

}
[/code]My Broadcaster looks now the following way:

[code]
public class Broadcaster implements Serializable {

static ExecutorService executorService = Executors
        .newSingleThreadExecutor();

private static Map<UI, BroadcastListener> listeners = new HashMap<>();

public static synchronized void register(UI ui, BroadcastListener listener) {
    listeners.put(ui, listener);
}

public static synchronized void unregister(UI ui) {
    listeners.remove(ui);
}

public static synchronized void broadcast(final String message) {
    for (final Map.Entry<UI, BroadcastListener> entry : listeners
            .entrySet()) {
        executorService.execute(new Runnable() {

            @Override
            public void run() {
                entry.getValue().receiveBroadcast(entry.getKey(), message);
            }
        });
    }
}

public interface BroadcastListener {
    void receiveBroadcast(UI ui, String message);
}

}
[/code]So, when I’m registering the listener I also provide a direct reference of the UI not using UI.getCurrent().
Just in case someone comes across the same problem, maybe he can use the informations here.

Greetings