summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Lumme <erik@vaadin.com>2017-09-13 14:51:59 +0300
committerErik Lumme <erik@vaadin.com>2017-09-13 14:51:59 +0300
commit13b585ffb7a50cfb86e30a52073d70dd25cb231c (patch)
tree4051120825fdbf4c2dd33f5a722dc3c2d3a9fb5c
parentcca89c574379d350fa0715a42eceb988b5c8b3f5 (diff)
downloadvaadin-framework-13b585ffb7a50cfb86e30a52073d70dd25cb231c.tar.gz
vaadin-framework-13b585ffb7a50cfb86e30a52073d70dd25cb231c.zip
Migrate BroadcastingMessagesToOtherUsers
-rw-r--r--documentation/articles/BroadcastingMessagesToOtherUsers.asciidoc129
-rw-r--r--documentation/articles/contents.asciidoc1
2 files changed, 130 insertions, 0 deletions
diff --git a/documentation/articles/BroadcastingMessagesToOtherUsers.asciidoc b/documentation/articles/BroadcastingMessagesToOtherUsers.asciidoc
new file mode 100644
index 0000000000..a61d3caed9
--- /dev/null
+++ b/documentation/articles/BroadcastingMessagesToOtherUsers.asciidoc
@@ -0,0 +1,129 @@
+[[broadcasting-messages-to-other-users]]
+Broadcasting messages to other users
+------------------------------------
+
+In this tutorial we will create an application where any user can send a
+broadcast message to all other active users. We will start from a
+project where push has been enabled (see link:EnablingServerPush.asciidoc[Enabling
+server push] for details).
+
+For simplicity, we will use a static `Broadcaster` which is shared between
+all users and all sessions. Each UI will register itself to this
+broadcast when initialized and unregister when detached. The broadcaster
+will take care of sending events to the registered UI:s as needed. In a
+real world scenario you probably want to use something else than a
+shared static class (e.g. JMS or some other messaging system) but the
+same ideas apply.
+
+So, let’s start from a simple `Broadcaster` class and a listener
+interface. We need the possibility to register and unregister listeners
+and to broadcast a message to the listeners so we end up with the
+following class:
+
+[source,java]
+....
+public class Broadcaster {
+
+ private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
+
+ public static void register(BroadcastListener listener) {
+ listeners.add(listener);
+ }
+
+ public static void unregister(BroadcastListener listener) {
+ listeners.remove(listener);
+ }
+
+ public static void broadcast(final String message) {
+ for (BroadcastListener listener : listeners) {
+ listener.receiveBroadcast(message);
+ }
+ }
+
+ public interface BroadcastListener {
+ public void receiveBroadcast(String message);
+ }
+}
+....
+
+As Broadcast will be used by many threads simultaneously, we need to
+ensure that it is thread-safe. We will do it here by using the
+thread-safe `CopyOnWriteArrayList` class for keeping track of the
+listeners.
+
+Now that we have the `Broadcaster` implemented we can use it in our UI for
+instance as follows:
+
+[source,java]
+....
+@Push
+public class BroadcasterUI extends UI implements BroadcastListener {
+
+ @Override
+ protected void init(VaadinRequest request) {
+ [...]
+ // Register broadcast listener
+ Broadcaster.register(this);
+ }
+
+ @Override
+ public void detach() {
+ Broadcaster.unregister(this);
+ super.detach();
+ }
+
+ @Override
+ public void receiveBroadcast(final String message) {
+ access(new Runnable() {
+ @Override
+ public void run() {
+ Notification n = new Notification("Message received",
+ message, Type.TRAY_NOTIFICATION);
+ n.show(getPage());
+ }
+ });
+ }
+....
+
+We register the UI in the init method and unregister it in the detach
+method to avoid receiving messages for UIs no longer in use (and
+ensuring that the detached UI can be garbage collected).
+
+When we receive a broadcast message we need to use the access method as
+this call comes from a thread where the UI is not locked.
+`access(Runnable)` will take care of locking the UI for us so we can
+update it. In the wrapped run method we can do whatever we like with the
+received message, for instance show it as a tray notification as done
+here.
+
+To send a broadcast message we can create a simple user interface in our
+UI init method:
+
+[source,java]
+....
+protected void init(VaadinRequest request) {
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ setContent(layout);
+
+ final TextArea message = new TextArea("",
+ "The system is going down for maintenance in 10 minutes");
+ layout.addComponent(message);
+
+ final Button button = new Button("Broadcast");
+ layout.addComponent(button);
+ button.addClickListener(new Button.ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ Broadcaster.broadcast(message.getValue());
+ }
+ });
+
+ // Register broadcast listener
+ Broadcaster.register(this);
+}
+....
+
+Now if you deploy the application and open it in a couple of browser
+tabs or separate browsers you are able to send messages between the
+instances.
diff --git a/documentation/articles/contents.asciidoc b/documentation/articles/contents.asciidoc
index ee59f2b632..b0987aee5b 100644
--- a/documentation/articles/contents.asciidoc
+++ b/documentation/articles/contents.asciidoc
@@ -88,3 +88,4 @@ are great, too.
- link:OpeningAUIInAPopupWindow.asciidoc[Opening a UI in a popup window]
- link:ViewChangeConfirmations.asciidoc[View change confirmations]
- link:CreatingABookmarkableApplicationWithBackButtonSupport.asciidoc[Creating a bookmarkable application with back button support]
+- link:BroadcastingMessagesToOtherUsers.asciidoc[Broadcasting messages to other users]