You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BroadcastingMessagesToOtherUsers.asciidoc 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. ---
  2. title: Broadcasting Messages To Other Users
  3. order: 82
  4. layout: page
  5. ---
  6. [[broadcasting-messages-to-other-users]]
  7. = Broadcasting messages to other users
  8. In this tutorial we will create an application where any user can send a
  9. broadcast message to all other active users. We will start from a
  10. project where push has been enabled (see <<EnablingServerPush#, Enabling
  11. server push>> for details).
  12. For simplicity, we will use a static `Broadcaster` which is shared between
  13. all users and all sessions. Each UI will register itself to this
  14. broadcast when initialized and unregister when detached. The broadcaster
  15. will take care of sending events to the registered UI:s as needed. In a
  16. real world scenario you probably want to use something else than a
  17. shared static class (e.g. JMS or some other messaging system) but the
  18. same ideas apply.
  19. So, let’s start from a simple `Broadcaster` class and a listener
  20. interface. We need the possibility to register and unregister listeners
  21. and to broadcast a message to the listeners so we end up with the
  22. following class:
  23. [source,java]
  24. ....
  25. public class Broadcaster {
  26. private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
  27. public static void register(BroadcastListener listener) {
  28. listeners.add(listener);
  29. }
  30. public static void unregister(BroadcastListener listener) {
  31. listeners.remove(listener);
  32. }
  33. public static void broadcast(final String message) {
  34. for (BroadcastListener listener : listeners) {
  35. listener.receiveBroadcast(message);
  36. }
  37. }
  38. public interface BroadcastListener {
  39. public void receiveBroadcast(String message);
  40. }
  41. }
  42. ....
  43. As Broadcast will be used by many threads simultaneously, we need to
  44. ensure that it is thread-safe. We will do it here by using the
  45. thread-safe `CopyOnWriteArrayList` class for keeping track of the
  46. listeners.
  47. Now that we have the `Broadcaster` implemented we can use it in our UI for
  48. instance as follows:
  49. [source,java]
  50. ....
  51. @Push
  52. public class BroadcasterUI extends UI implements BroadcastListener {
  53. @Override
  54. protected void init(VaadinRequest request) {
  55. [...]
  56. // Register broadcast listener
  57. Broadcaster.register(this);
  58. }
  59. @Override
  60. public void detach() {
  61. Broadcaster.unregister(this);
  62. super.detach();
  63. }
  64. @Override
  65. public void receiveBroadcast(final String message) {
  66. access(new Runnable() {
  67. @Override
  68. public void run() {
  69. Notification n = new Notification("Message received",
  70. message, Type.TRAY_NOTIFICATION);
  71. n.show(getPage());
  72. }
  73. });
  74. }
  75. ....
  76. We register the UI in the init method and unregister it in the detach
  77. method to avoid receiving messages for UIs no longer in use (and
  78. ensuring that the detached UI can be garbage collected).
  79. When we receive a broadcast message we need to use the access method as
  80. this call comes from a thread where the UI is not locked.
  81. `access(Runnable)` will take care of locking the UI for us so we can
  82. update it. In the wrapped run method we can do whatever we like with the
  83. received message, for instance show it as a tray notification as done
  84. here.
  85. To send a broadcast message we can create a simple user interface in our
  86. UI init method:
  87. [source,java]
  88. ....
  89. protected void init(VaadinRequest request) {
  90. final VerticalLayout layout = new VerticalLayout();
  91. layout.setMargin(true);
  92. setContent(layout);
  93. final TextArea message = new TextArea("",
  94. "The system is going down for maintenance in 10 minutes");
  95. layout.addComponent(message);
  96. final Button button = new Button("Broadcast");
  97. layout.addComponent(button);
  98. button.addClickListener(new Button.ClickListener() {
  99. @Override
  100. public void buttonClick(ClickEvent event) {
  101. Broadcaster.broadcast(message.getValue());
  102. }
  103. });
  104. // Register broadcast listener
  105. Broadcaster.register(this);
  106. }
  107. ....
  108. Now if you deploy the application and open it in a couple of browser
  109. tabs or separate browsers you are able to send messages between the
  110. instances.