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.

Heartbeat.java 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2000-2021 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client.communication;
  17. import java.util.logging.Logger;
  18. import com.google.gwt.http.client.Request;
  19. import com.google.gwt.http.client.RequestBuilder;
  20. import com.google.gwt.http.client.RequestCallback;
  21. import com.google.gwt.http.client.RequestException;
  22. import com.google.gwt.http.client.Response;
  23. import com.google.gwt.user.client.Timer;
  24. import com.vaadin.client.ApplicationConnection;
  25. import com.vaadin.shared.ApplicationConstants;
  26. import com.vaadin.shared.ui.ui.UIConstants;
  27. import com.vaadin.shared.util.SharedUtil;
  28. /**
  29. * Handles sending of heartbeats to the server and reacting to the response.
  30. *
  31. * @since 7.2
  32. * @author Vaadin Ltd
  33. */
  34. public class Heartbeat {
  35. private Timer timer = new Timer() {
  36. @Override
  37. public void run() {
  38. send();
  39. }
  40. };
  41. private ApplicationConnection connection;
  42. private String uri;
  43. private int interval = -1;
  44. private static Logger getLogger() {
  45. return Logger.getLogger(Heartbeat.class.getName());
  46. }
  47. /**
  48. * Initializes the heartbeat for the given application connection.
  49. *
  50. * @param applicationConnection
  51. * the connection
  52. */
  53. public void init(ApplicationConnection applicationConnection) {
  54. connection = applicationConnection;
  55. setInterval(connection.getConfiguration().getHeartbeatInterval());
  56. uri = SharedUtil.addGetParameters(
  57. connection.translateVaadinUri(
  58. ApplicationConstants.APP_PROTOCOL_PREFIX
  59. + ApplicationConstants.HEARTBEAT_PATH + '/'),
  60. UIConstants.UI_ID_PARAMETER + "="
  61. + connection.getConfiguration().getUIId());
  62. connection.addHandler(
  63. ApplicationConnection.ApplicationStoppedEvent.TYPE,
  64. event -> setInterval(-1));
  65. }
  66. /**
  67. * Sends a heartbeat to the server.
  68. */
  69. public void send() {
  70. timer.cancel();
  71. final RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, uri);
  72. XhrConnection.addXsrfHeaderFromCookie(rb);
  73. final RequestCallback callback = new RequestCallback() {
  74. @Override
  75. public void onResponseReceived(Request request, Response response) {
  76. int status = response.getStatusCode();
  77. if (status == Response.SC_OK) {
  78. connection.getConnectionStateHandler().heartbeatOk();
  79. } else {
  80. // Handler should stop the application if heartbeat should
  81. // no longer be sent
  82. connection.getConnectionStateHandler()
  83. .heartbeatInvalidStatusCode(request, response);
  84. }
  85. schedule();
  86. }
  87. @Override
  88. public void onError(Request request, Throwable exception) {
  89. // Handler should stop the application if heartbeat should no
  90. // longer be sent
  91. connection.getConnectionStateHandler()
  92. .heartbeatException(request, exception);
  93. schedule();
  94. }
  95. };
  96. rb.setCallback(callback);
  97. try {
  98. getLogger().fine("Sending heartbeat request...");
  99. rb.send();
  100. } catch (RequestException re) {
  101. callback.onError(null, re);
  102. }
  103. }
  104. /**
  105. * @return the interval at which heartbeat requests are sent
  106. */
  107. public int getInterval() {
  108. return interval;
  109. }
  110. /**
  111. * Updates the schedule of the heartbeat to match the set interval. A
  112. * negative interval disables the heartbeat.
  113. */
  114. public void schedule() {
  115. if (interval > 0) {
  116. getLogger()
  117. .fine("Scheduling heartbeat in " + interval + " seconds");
  118. timer.schedule(interval * 1000);
  119. } else {
  120. getLogger().fine("Disabling heartbeat");
  121. timer.cancel();
  122. }
  123. }
  124. /**
  125. * @return the application connection
  126. */
  127. @Deprecated
  128. protected ApplicationConnection getConnection() {
  129. return connection;
  130. }
  131. /**
  132. * Changes the heartbeatInterval in runtime and applies it.
  133. *
  134. * @param heartbeatInterval
  135. * new interval in seconds.
  136. */
  137. public void setInterval(int heartbeatInterval) {
  138. getLogger().info(
  139. "Setting hearbeat interval to " + heartbeatInterval + "sec.");
  140. interval = heartbeatInterval;
  141. schedule();
  142. }
  143. }