WebSocketClient.java

  1. package gov.usgs.earthquake.distribution;

  2. import javax.websocket.*;

  3. import java.io.IOException;
  4. import java.net.URI;

  5. /**
  6.  * Manages a simple connection to a websocket. Can also be overridden for more complex behavior.
  7.  */
  8. @ClientEndpoint
  9. public class WebSocketClient {

  10.   private Session session;

  11.   private URI endpoint;
  12.   private WebSocketListener listener;
  13.   private int attempts;
  14.   private long timeoutMillis;
  15.   private boolean retryOnClose;

  16.   /** Default number of attempts */
  17.   public static final int DEFAULT_ATTEMPTS = 3;
  18.   /** Default timeout in ms */
  19.   public static final long DEFAULT_TIMEOUT_MILLIS = 100;
  20.   /** Default for trying to retry on close */
  21.   public static final boolean DEFAULT_RETRY_ON_CLOSE = true;

  22.   /**
  23.    * Constructs the client. Also connects to the server.
  24.    *
  25.    * @param endpoint the URI to connect to
  26.    * @param listener a WebSocketListener to handle incoming messages
  27.    * @param attempts an integer number of times to try the connection
  28.    * @param timeoutMillis a long for the wait time between attempts
  29.    * @param retryOnClose boolean for if the connection should retry when closed
  30.    * @throws Exception on thread interrupt or connection failure
  31.    */
  32.   public WebSocketClient(URI endpoint, WebSocketListener listener, int attempts, long timeoutMillis, boolean retryOnClose) throws Exception {
  33.     this.listener = listener;
  34.     this.endpoint = endpoint;
  35.     this.attempts = attempts;
  36.     this.timeoutMillis = timeoutMillis;
  37.     this.retryOnClose = retryOnClose;

  38.     connect();
  39.   }

  40.   /**
  41.    * Constructs the client
  42.    * @param endpoint the URI to connect to
  43.    * @param listener a WebSocketListener to handle incoming messages
  44.    * @throws Exception thread interrupt or connection failure
  45.    */
  46.   public WebSocketClient(URI endpoint, WebSocketListener listener) throws Exception {
  47.     this(endpoint, listener, DEFAULT_ATTEMPTS, DEFAULT_TIMEOUT_MILLIS, DEFAULT_RETRY_ON_CLOSE);
  48.   }

  49.   /**
  50.    * Connect to server
  51.    * @throws Exception if error occurs
  52.    */
  53.   public void connect() throws Exception {
  54.     // try to connect to server
  55.     WebSocketContainer container = ContainerProvider.getWebSocketContainer();
  56.     int failedAttempts = 0;
  57.     Exception lastExcept = null;
  58.     for (int i = 0; i < attempts; i++) {
  59.       try {
  60.         container.connectToServer(this, endpoint);
  61.         break;
  62.       } catch (Exception e) {
  63.         // increment failed attempts, sleep
  64.         failedAttempts++;
  65.         lastExcept = e;
  66.         Thread.sleep(timeoutMillis);
  67.       }
  68.     }

  69.     // throw connect exception if all attempts fail
  70.     if (failedAttempts == attempts) {
  71.       this.listener.onConnectFail();
  72.       throw lastExcept;
  73.     }
  74.   }

  75.   /**
  76.    * Sets the session and listener
  77.    * @param session Session
  78.    * @throws IOException if IO error occurs
  79.    */
  80.   @OnOpen
  81.   public void onOpen(Session session) throws IOException {
  82.     this.session = session;
  83.     this.listener.onOpen(session);
  84.   }

  85.   /**
  86.    * Closes the session on the lister, sets constructor session to null
  87.    * Check if should be retryed
  88.    * @param session Session
  89.    * @param reason for close
  90.    * @throws IOException if IO error occurs
  91.    */
  92.   @OnClose
  93.   public void onClose(Session session, CloseReason reason) throws IOException {
  94.     this.listener.onClose(session, reason);
  95.     this.session = null;
  96.     if (retryOnClose) {
  97.       try {
  98.         this.connect();
  99.       } catch (Exception e) {
  100.         // failed to reconnect
  101.         this.listener.onReconnectFail();
  102.       }
  103.     }
  104.   }

  105.   /**
  106.    * Gives listener the message
  107.    * @param message String
  108.    * @throws IOException if IO error occurs
  109.    */
  110.   @OnMessage
  111.   public void onMessage(String message) throws IOException {
  112.     this.listener.onMessage(message);
  113.   }

  114.   /**
  115.    * Sets retry to false, then closes session
  116.    * @throws Exception if error occurs
  117.    */
  118.   public void shutdown() throws Exception {
  119.     this.retryOnClose = false;
  120.     this.session.close();
  121.   }

  122.   /** @param listener set WebSocketListener */
  123.   public void setListener(WebSocketListener listener) {
  124.     this.listener = listener;
  125.   }

  126.   /**
  127.    * Checks if there is an open session
  128.    * @return boolean
  129.    * @throws IOException if IO error occurs
  130.    */
  131.   public boolean isConnected() throws IOException {
  132.     return this.session != null && this.session.isOpen();
  133.   }

  134. }