/**
   * Sends a message envelope on this socket
   *
   * @param envelope The message envelope
   * @return This socket instance
   * @throws IOException Thrown if the message cannot be sent
   */
  public Socket push(final Envelope envelope) throws IOException {
    LOG.log(Level.FINE, "Pushing envelope: {0}", envelope);
    final ObjectNode node = objectMapper.createObjectNode();
    node.put("topic", envelope.getTopic());
    node.put("event", envelope.getEvent());
    node.put("ref", envelope.getRef());
    node.set(
        "payload",
        envelope.getPayload() == null ? objectMapper.createObjectNode() : envelope.getPayload());
    final String json = objectMapper.writeValueAsString(node);
    LOG.log(Level.FINE, "Sending JSON: {0}", json);

    RequestBody body = RequestBody.create(WebSocket.TEXT, json);

    if (this.isConnected()) {
      try {
        webSocket.sendMessage(body);
      } catch (IllegalStateException e) {
        LOG.log(Level.SEVERE, "Attempted to send push when socket is not open", e);
      }
    } else {
      this.sendBuffer.add(body);
    }

    return this;
  }
 public void disconnect() throws IOException {
   LOG.log(Level.FINE, "disconnect");
   if (webSocket != null) {
     webSocket.close(1001 /*CLOSE_GOING_AWAY*/, "Disconnected by client");
     cancelHeartbeatTimer();
   }
 }