@Test
 public void testSharedServersRoundRobinButFirstStartAndStopServer() throws Exception {
   // Start and stop a server on the same port/host before hand to make sure it doesn't interact
   CountDownLatch latch = new CountDownLatch(1);
   HttpServer theServer = vertx.createHttpServer(new HttpServerOptions().setPort(4321));
   theServer
       .websocketHandler(
           ws -> {
             fail("Should not connect");
           })
       .listen(
           ar -> {
             if (ar.succeeded()) {
               latch.countDown();
             } else {
               fail("Failed to bind server");
             }
           });
   awaitLatch(latch);
   CountDownLatch closeLatch = new CountDownLatch(1);
   theServer.close(
       ar -> {
         assertTrue(ar.succeeded());
         closeLatch.countDown();
       });
   assertTrue(closeLatch.await(10, TimeUnit.SECONDS));
   testSharedServersRoundRobin();
 }
  @Override
  public void start() throws Exception {

    HttpServer server = vertx.createHttpServer();
    server.requestHandler(
        new Handler<HttpServerRequest>() {

          @Override
          public void handle(HttpServerRequest request) {
            request
                .response()
                .sendFile(
                    '.' + (request.path().equals("/") ? "/resource/index.html" : request.path()));
          }
        });

    server.websocketHandler(
        new Handler<ServerWebSocket>() {

          @Override
          public void handle(final ServerWebSocket ws) {
            if (!ws.path().equals("/chat")) {
              ws.reject();
              return;
            }
            final LocalMap<Object, String> wsSessions =
                vertx.sharedData().getLocalMap("websocket.chat.sessions");
            if (wsSessions == null) {
              System.out.println("Deu erro!");
            }
            wsSessions.put(ws.textHandlerID(), ws.textHandlerID());

            ws.handler(
                new Handler<Buffer>() {

                  @Override
                  public void handle(Buffer buffer) {
                    for (String handlerId : wsSessions.values()) {
                      System.err.println("Sending " + handlerId);
                      vertx.eventBus().send(handlerId, buffer.toString());
                    }
                  }
                });

            ws.closeHandler(
                new Handler<Void>() {

                  @Override
                  public void handle(Void v) {
                    System.err.println("Socket closed. Removing" + ws.binaryHandlerID());
                    wsSessions.remove(ws.textHandlerID());
                  }
                });
          }
        });

    server.listen(8080);
  }
  @Override
  public void start() throws Exception {
    address = MQTTSession.ADDRESS;

    JsonObject conf = config();

    localBridgePort = conf.getInteger("local_bridge_port", 7007);
    idleTimeout = conf.getInteger("socket_idle_timeout", 120);
    ssl_cert_key = conf.getString("ssl_cert_key");
    ssl_cert = conf.getString("ssl_cert");
    ssl_trust = conf.getString("ssl_trust");

    // [WebSocket -> BUS] listen WebSocket publish to BUS
    HttpServerOptions opt =
        new HttpServerOptions()
            .setTcpKeepAlive(true)
            .setIdleTimeout(idleTimeout)
            .setPort(localBridgePort);

    if (ssl_cert_key != null && ssl_cert != null && ssl_trust != null) {
      opt.setSsl(true)
          .setClientAuth(ClientAuth.REQUIRED)
          .setPemKeyCertOptions(
              new PemKeyCertOptions().setKeyPath(ssl_cert_key).setCertPath(ssl_cert))
          .setPemTrustOptions(new PemTrustOptions().addCertPath(ssl_trust));
    }

    netServer = vertx.createHttpServer(opt);
    netServer
        .websocketHandler(
            sock -> {
              final EventBusWebsocketBridge ebnb =
                  new EventBusWebsocketBridge(sock, vertx.eventBus(), address);
              sock.closeHandler(
                  aVoid -> {
                    logger.info(
                        "Bridge Server - closed connection from client ip: "
                            + sock.remoteAddress());
                    ebnb.stop();
                  });
              sock.exceptionHandler(
                  throwable -> {
                    logger.error("Bridge Server - Exception: " + throwable.getMessage(), throwable);
                    ebnb.stop();
                  });

              logger.info("Bridge Server - new connection from client ip: " + sock.remoteAddress());

              RecordParser parser = ebnb.initialHandhakeProtocolParser();
              sock.handler(parser::handle);
            })
        .listen();
  }
 @Test
 public void testSharedServersRoundRobinWithOtherServerRunningOnDifferentPort() throws Exception {
   // Have a server running on a different port to make sure it doesn't interact
   CountDownLatch latch = new CountDownLatch(1);
   HttpServer theServer = vertx.createHttpServer(new HttpServerOptions().setPort(4321));
   theServer
       .websocketHandler(
           ws -> {
             fail("Should not connect");
           })
       .listen(
           ar -> {
             if (ar.succeeded()) {
               latch.countDown();
             } else {
               fail("Failed to bind server");
             }
           });
   awaitLatch(latch);
   testSharedServersRoundRobin();
 }
  @Test
  public void testSharedServersRoundRobin() throws Exception {

    int numServers = 5;
    int numConnections = numServers * 100;

    List<HttpServer> servers = new ArrayList<>();
    Set<HttpServer> connectedServers = new ConcurrentHashSet<>();
    Map<HttpServer, Integer> connectCount = new ConcurrentHashMap<>();

    CountDownLatch latchListen = new CountDownLatch(numServers);
    CountDownLatch latchConns = new CountDownLatch(numConnections);
    for (int i = 0; i < numServers; i++) {
      HttpServer theServer =
          vertx.createHttpServer(new HttpServerOptions().setPort(HttpTestBase.DEFAULT_HTTP_PORT));
      servers.add(theServer);
      theServer
          .websocketHandler(
              ws -> {
                connectedServers.add(theServer);
                Integer cnt = connectCount.get(theServer);
                int icnt = cnt == null ? 0 : cnt;
                icnt++;
                connectCount.put(theServer, icnt);
                latchConns.countDown();
              })
          .listen(
              ar -> {
                if (ar.succeeded()) {
                  latchListen.countDown();
                } else {
                  fail("Failed to bind server");
                }
              });
    }
    assertTrue(latchListen.await(10, TimeUnit.SECONDS));

    // Create a bunch of connections
    CountDownLatch latchClient = new CountDownLatch(numConnections);
    for (int i = 0; i < numConnections; i++) {
      client.connectWebsocket(
          HttpTestBase.DEFAULT_HTTP_PORT,
          HttpTestBase.DEFAULT_HTTP_HOST,
          "/someuri",
          ws -> {
            ws.closeHandler(v -> latchClient.countDown());
            ws.close();
          });
    }

    assertTrue(latchClient.await(10, TimeUnit.SECONDS));
    assertTrue(latchConns.await(10, TimeUnit.SECONDS));

    assertEquals(numServers, connectedServers.size());
    for (HttpServer server : servers) {
      assertTrue(connectedServers.contains(server));
    }
    assertEquals(numServers, connectCount.size());
    for (int cnt : connectCount.values()) {
      assertEquals(numConnections / numServers, cnt);
    }

    CountDownLatch closeLatch = new CountDownLatch(numServers);

    for (HttpServer server : servers) {
      server.close(
          ar -> {
            assertTrue(ar.succeeded());
            closeLatch.countDown();
          });
    }

    assertTrue(closeLatch.await(10, TimeUnit.SECONDS));

    testComplete();
  }
 private void testTLS(
     KS clientCert,
     TS clientTrust,
     KS serverCert,
     TS serverTrust,
     boolean requireClientAuth,
     boolean serverUsesCrl,
     boolean clientTrustAll,
     boolean clientUsesCrl,
     boolean shouldPass,
     String... enabledCipherSuites)
     throws Exception {
   HttpClientOptions options = new HttpClientOptions();
   options.setSsl(true);
   if (clientTrustAll) {
     options.setTrustAll(true);
   }
   if (clientUsesCrl) {
     options.addCrlPath(findFileOnClasspath("tls/ca/crl.pem"));
   }
   options.setTrustStoreOptions(getClientTrustOptions(clientTrust));
   options.setKeyStoreOptions(getClientCertOptions(clientCert));
   for (String suite : enabledCipherSuites) {
     options.addEnabledCipherSuite(suite);
   }
   client = vertx.createHttpClient(options);
   HttpServerOptions serverOptions = new HttpServerOptions();
   serverOptions.setSsl(true);
   serverOptions.setTrustStoreOptions(getServerTrustOptions(serverTrust));
   serverOptions.setKeyStoreOptions(getServerCertOptions(serverCert));
   if (requireClientAuth) {
     serverOptions.setClientAuthRequired(true);
   }
   if (serverUsesCrl) {
     serverOptions.addCrlPath(findFileOnClasspath("tls/ca/crl.pem"));
   }
   for (String suite : enabledCipherSuites) {
     serverOptions.addEnabledCipherSuite(suite);
   }
   server = vertx.createHttpServer(serverOptions.setPort(4043));
   server.websocketHandler(
       ws -> {
         ws.handler(ws::write);
       });
   server.listen(
       ar -> {
         assertTrue(ar.succeeded());
         client
             .websocket(4043, HttpTestBase.DEFAULT_HTTP_HOST, "/")
             .exceptionHandler(
                 t -> {
                   if (shouldPass) {
                     t.printStackTrace();
                     fail("Should not throw exception");
                   } else {
                     testComplete();
                   }
                 })
             .handler(
                 ws -> {
                   int size = 100;
                   Buffer received = Buffer.buffer();
                   ws.handler(
                       data -> {
                         received.appendBuffer(data);
                         if (received.length() == size) {
                           ws.close();
                           testComplete();
                         }
                       });
                   Buffer buff = Buffer.buffer(TestUtils.randomByteArray(size));
                   ws.writeFrame(WebSocketFrame.binaryFrame(buff, true));
                 });
       });
   await();
 }