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.

UsingRPCToSendEventsToTheClient.asciidoc 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. ---
  2. title: Using RPC To Send Events To The Client
  3. order: 56
  4. layout: page
  5. ---
  6. [[using-rpc-to-send-events-to-the-client]]
  7. Using RPC to send events to the client
  8. --------------------------------------
  9. An RPC mechanism can be used to communicate from the server to the
  10. client. In effect, the server-side component can call methods that are
  11. executed by the client-side connector. As opposed to shared state
  12. (discussed in a separate article), no information is automatically
  13. re-transmitted when the client-side state is lost (e.g when a browser
  14. reload is invoked).
  15. Whether shared state or RPC is appropriate depends on the nature of the
  16. data being transmitted, but if the information transmitted needs to be
  17. retained on the client over a page refresh, you should probably use
  18. shared state. You'll probably find shared state more appropriate in most
  19. cases, and server-client RPC extremely useful in a few cases.
  20. To set up server-client RPC, we need to create an interface extending
  21. `ClientRpc` for the RPC methods, then register an implementation of the
  22. RPC interface in the client-side connector, and call the method(s) via a
  23. proxy on the server. This is the reverse of the server-client RPC
  24. described in a separate article.
  25. We'll create *MyComponentClientRpc* in the client package:
  26. [source,java]
  27. ....
  28. package com.example.mycomponent.client;
  29. import com.vaadin.client.communication.ClientRpc;
  30. public interface MyComponentClientRpc extends ClientRpc {
  31. public void alert(String message);
  32. }
  33. ....
  34. Again, note that the RPC methods can not return anything, but can take
  35. multiple arguments.
  36. In *MyComponentConnector* we register the RPC implementation in the
  37. constructor. This time we'll create the implementation inline:
  38. [source,java]
  39. ....
  40. package com.example.mycomponent.client;
  41. // imports removed for clarity
  42. @Connect(MyComponent.class)
  43. public class MyComponentConnector extends AbstractComponentConnector {
  44. MyComponentServerRpc rpc = RpcProxy
  45. .create(MyComponentServerRpc.class, this);
  46. public MyComponentConnector() {
  47. registerRpc(MyComponentClientRpc.class, new MyComponentClientRpc() {
  48. public void alert(String message) {
  49. Window.alert(message);
  50. }
  51. });
  52. /* The rest of the code remains unchanged:
  53. getWidget().addClickHandler(new ClickHandler() {
  54. public void onClick(ClickEvent event) {
  55. final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
  56. .buildMouseEventDetails(event.getNativeEvent(),
  57. getWidget().getElement());
  58. rpc.clicked(mouseDetails);
  59. }
  60. });
  61. }
  62. @Override
  63. protected Widget createWidget() {
  64. return GWT.create(MyComponentWidget.class);
  65. }
  66. @Override
  67. public MyComponentWidget getWidget() {
  68. return (MyComponentWidget) super.getWidget();
  69. }
  70. @Override
  71. public MyComponentState getState() {
  72. return (MyComponentState) super.getState();
  73. }
  74. @OnStateChange("text")
  75. void updateText() {
  76. getWidget().setText(getState().text);
  77. }
  78. */
  79. }
  80. ....
  81. (`MyComponentServerRpc` is introduced in
  82. <<SendingEventsFromTheClientToTheServerUsingRPC#
  83. sending-events-from-the-client-to-the-server-using-RPC,
  84. Sending events from the client to the server using RPC>>. `Window` here is
  85. `com.google.gwt.user.client.Window`, _not_ `com.vaadin.ui.Window`.)
  86. Finally, in *MyComponent* we use the RPC via a proxy:
  87. [source,java]
  88. ....
  89. import com.vaadin.ui.AbstractComponent;
  90. public class MyComponent extends AbstractComponent {
  91. private int clickCount = 0;
  92. private MyComponentServerRpc rpc = new MyComponentServerRpc() {
  93. public void clicked(MouseEventDetails mouseDetails) {
  94. clickCount++;
  95. // nag every 5:th click
  96. if (clickCount % 5 == 0) {
  97. getRpcProxy(MyComponentClientRpc.class).alert(
  98. "Ok, that's enough!");
  99. }
  100. setText("You have clicked " + clickCount + " times");
  101. }
  102. };
  103. /* Unchanged code follows:
  104. public MyComponent() {
  105. registerRpc(rpc);
  106. }
  107. @Override
  108. public MyComponentState getState() {
  109. return (MyComponentState) super.getState();
  110. }
  111. public void setText(String text) {
  112. getState().text = text;
  113. }
  114. public String getText() {
  115. return getState().text;
  116. }
  117. */
  118. }
  119. ....
  120. That is: every fifth time the label is clicked, we get the RPC proxy by
  121. calling `getRpcProxy()` and call our `alert()` method with a message to
  122. send to the client.
  123. Compile the widgetset, and you're all set to try out server-client RPC.