// Constructor
  public Client(WebSocketTransport ws) {
    this.ws = ws;
    ws.setHandler(this);

    prepareExecutor();
    // requires executor, so call after prepareExecutor
    scheduleMaintenance();

    subscriptions.on(
        SubscriptionManager.OnSubscribed.class,
        new SubscriptionManager.OnSubscribed() {
          @Override
          public void called(JSONObject subscription) {
            if (!connected) return;
            subscribe(subscription);
          }
        });
  }
  public void sendMessage(JSONObject object) {
    if (logger.isLoggable(Level.FINER)) {
      logger.log(Level.FINER, "Send: {0}", prettyJSON(object));
    }

    timer = System.currentTimeMillis();
    emit(OnSendMessage.class, object);
    ws.sendMessage(object);

    if (randomBugsFrequency != 0) {
      if (randomBugs.nextDouble() > (1D - randomBugsFrequency)) {
        disconnect();
        connect(previousUri);
        String msg = "I disconnected you, now I'm gonna throw, " + "deal with it suckah! ;)";
        logger.warning(msg);
        throw new RuntimeException(msg);
      }
    }
  }
 public void disconnect() {
   manuallyDisconnected = true;
   ws.disconnect();
   // our disconnect handler should do the rest
 }
 public void doConnect(String uri) {
   log(Level.INFO, "Connecting to " + uri);
   previousUri = uri;
   ws.connect(URI.create(uri));
 }
 @Override
 public void setProxy(Proxy proxy) {
   ws.setProxy(proxy);
 }