Example usage for io.netty.bootstrap ServerBootstrap group

List of usage examples for io.netty.bootstrap ServerBootstrap group

Introduction

In this page you can find the example usage for io.netty.bootstrap ServerBootstrap group.

Prototype

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) 

Source Link

Document

Set the EventLoopGroup for the parent (acceptor) and the child (client).

Usage

From source file:freddo.dtalk2.broker.netty.NettyBroker.java

License:Apache License

@Override
public void start() {
    ServerBootstrap b = new ServerBootstrap();
    b.group(mBossGroup, mWorkerGroup).handler(new LoggingHandler(LogLevel.INFO))
            .channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
                @Override//from   w ww  .  j  a  v a  2 s .com
                protected void initChannel(SocketChannel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
                    // if (sslCtx != null) {
                    // pipeline.addLast(sslCtx.newHandler(ch.alloc()));
                    // }
                    pipeline.addLast(new HttpServerCodec());
                    pipeline.addLast(new HttpObjectAggregator(65536));
                    pipeline.addLast(new NettyBrokerHandler());
                }
            });

    try {
        // Bind and start to accept incoming connections.
        Channel ch = b.bind(mSocketAddress).sync().channel();
        mSocketAddress = (InetSocketAddress) ch.localAddress();
        LOG.info("Server binded host: {}, port: {}", mSocketAddress.getHostName(), mSocketAddress.getPort());
    } catch (InterruptedException ex) {
        LOG.error(null, ex);
    }
}

From source file:game.net.websocket.WebSocketServer.java

License:Apache License

public void start() throws Exception {
    // Configure SSL.
    final SslContext sslCtx;
    if (SSL) {/*from   w w  w  .  j  a va 2 s.c  o  m*/
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
    } else {
        sslCtx = null;
    }

    bossGroup = new NioEventLoopGroup(1);
    workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new WebSocketServerInitializer(sslCtx));

        Channel ch = b.bind(PORT).sync().channel();

        System.out.println("Open your web browser and navigate to " + (SSL ? "https" : "http") + "://127.0.0.1:"
                + PORT + '/');

        ch.closeFuture().sync();

    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

From source file:gedi.remote.RemoteConnections.java

License:Apache License

/**
 * Returns without blocking!/*from   w  w  w  .  j a  v a  2s .c  om*/
 * @param url
 * @param handler
 * @return
 */
public void serveSync(Protocol protocol, final Consumer<SocketChannel> initChannel) {

    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .handler(new ConfigLoggingHandler(ConfigLoggingHandler.LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {

                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new ConfigLoggingHandler(ConfigLoggingHandler.LogLevel.INFO));
                        protocol.setCodecs(pipeline);
                        initChannel.accept(ch);
                    }
                });

        ChannelFuture f = b.bind(protocol.getDefaultPort()).sync();
        log.log(Level.INFO,
                "Server thread started for protocol " + protocol + " on port " + protocol.getDefaultPort());

        f.channel().closeFuture().sync();

    } catch (InterruptedException e) {
        log.log(Level.SEVERE, "Server thread interrupted", e);
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }

}

From source file:gribbit.http.server.GribbitHttpServer.java

License:Open Source License

/**
 * Start the HTTP server./*from   w w  w  .j  av a  2 s. c o  m*/
 * 
 * @throws IllegalArgumentException
 *             if port is already in use, or the server cannot be started for some other reason.
 */
public GribbitHttpServer start() {
    if (channel != null) {
        throw new IllegalArgumentException(serverName + " has already been started");
    }

    if (port == null) {
        port = useTLS ? 8443 : 8080;
    }

    // Initialize logger
    Log.info("Starting " + serverName + " on port " + port);

    if (!portAvailable(port)) {
        throw new IllegalArgumentException("Port " + port + " is not available -- is server already running?");
    }

    // TODO: allow the number of threads to be configurable?
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    EventLoopGroup requestDecoderGroup = new NioEventLoopGroup();
    try {
        final SslContext sslCtx = useTLS ? configureTLS() : null;

        ServerBootstrap b = new ServerBootstrap();
        // http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#14.0
        //b.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

        //b.option(ChannelOption.SO_BACKLOG, 1024);
        b.group(bossGroup, workerGroup) //
                .channel(NioServerSocketChannel.class) //
                .handler(new LoggingHandler(LogLevel.DEBUG)) //
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    // Create an HTTP decoder/encoder and request handler for each connection,
                    // so that the request can be handled in a stateful way
                    @Override
                    public void initChannel(SocketChannel ch) {
                        ChannelPipeline p = ch.pipeline();
                        HttpRequestDecoder httpRequestDecoder = new HttpRequestDecoder(httpRequestHandlers,
                                webSocketHandlers, errorHandlers);
                        if (sslCtx != null) {
                            p.addLast(sslCtx.newHandler(ch.alloc()),
                                    new Http2OrHttpHandler(requestDecoderGroup, httpRequestDecoder)); // TODO: correct for HTTP2?
                        } else {
                            // TODO: unify this with HTTP 1.1 treatment in http2OrHttpHandler

                            p.addLast(new HttpServerCodec());
                            p.addLast(new HttpContentDecompressor());
                            p.addLast(new HttpObjectAggregator(65536));
                            p.addLast(new ChunkedWriteHandler());
                            // The name is needed in the last handler, because it is used to dynamically add in
                            // HttpContentCompressor if the content in the response needs to be compressed.
                            p.addLast(HttpRequestDecoder.NAME_IN_PIPELINE, httpRequestDecoder);

                            //                                // p.addLast(new HttpContentDecompressor());
                            //                                p.addLast(new HttpServerCodec());
                            //                                // TODO: We're currently doing manual aggregation of chunked requests
                            //                                // (without limiting len) 
                            //                                p.addLast(new HttpObjectAggregator(65536));
                            //                                p.addLast(new ChunkedWriteHandler());
                            //                                // p.addLast(new WebSocketServerCompressionHandler());
                            //                                p.addLast(/*requestDecoderGroup, */ httpRequestDecoder);
                        }
                    }
                });

        //    // TODO: test these options suggested in http://goo.gl/AHvjmq
        //    // See also http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#11.0
        //    b.childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 64 * 1024);
        //    b.childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, 64 * 1024);
        //    b.childOption(ChannelOption.SO_SNDBUF, 1048576);
        //    b.childOption(ChannelOption.SO_RCVBUF, 1048576);
        //    // bootstrap.childOption(ChannelOption.TCP_NODELAY, true);

        // TODO: Apache closes KeepAlive connections after a few seconds, see
        //       http://en.wikipedia.org/wiki/HTTP_persistent_connection
        // TODO: implement a stale connection tracker
        // final StaleConnectionTrackingHandler staleConnectionTrackingHandler = 
        //          new StaleConnectionTrackingHandler(STALE_CONNECTION_TIMEOUT, executor);
        //            ScheduledExecutorService staleCheckExecutor = 
        //               Executors.newSingleThreadScheduledExecutor(
        //                 new NamingThreadFactory(Gribbit.class.getSimpleName()
        //                    + "-stale-connection-check"));
        //            staleCheckExecutor.scheduleWithFixedDelay(new Runnable() {
        //                @Override
        //                public void run() {
        //                    staleConnectionTrackingHandler.closeStaleConnections();
        //                }
        //            }, STALE_CONNECTION_TIMEOUT / 2, STALE_CONNECTION_TIMEOUT / 2,
        //                TimeUnit.MILLISECONDS);
        //            executorServices.add(staleCheckExecutor);
        // connectionTrackingHandler = new ConnectionTrackingHandler();

        String domainAndPort = domain + ((!useTLS && port == 80) || (useTLS && port == 443) ? "" : ":" + port);
        uri = new URI((useTLS ? "https" : "http") + "://" + domainAndPort);
        wsUri = new URI((useTLS ? "wss" : "ws") + "://" + domainAndPort);

        // Set up channel
        channel = b.bind(port).sync().channel();

        Log.info(serverName + " started at " + uri + "/");

        // Wait (possibly indefinitely) for channel to close via call to this.shutdown()
        channel.closeFuture().sync();
        channel = null;

        Log.info(serverName + " successfully shut down");

    } catch (Exception e) {
        throw new RuntimeException("Could not start server", e);

    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
        requestDecoderGroup.shutdownGracefully();
    }
    return this;
}

From source file:herddb.network.netty.NettyChannelAcceptor.java

License:Apache License

public void start() throws Exception {
    if (ssl) {/*from   w  w w. j  a v a2 s  .  c om*/
        if (sslCertFile == null) {
            LOGGER.log(Level.SEVERE, "start SSL with self-signed auto-generated certificate");
            if (sslCiphers != null) {
                LOGGER.log(Level.SEVERE, "required sslCiphers " + sslCiphers);
            }
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            try {
                sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).ciphers(sslCiphers)
                        .build();
            } finally {
                ssc.delete();
            }
        } else {
            LOGGER.log(Level.SEVERE, "start SSL with certificate " + sslCertFile.getAbsolutePath()
                    + " chain file " + sslCertChainFile.getAbsolutePath());
            if (sslCiphers != null) {
                LOGGER.log(Level.SEVERE, "required sslCiphers " + sslCiphers);
            }
            sslCtx = SslContextBuilder.forServer(sslCertChainFile, sslCertFile, sslCertPassword)
                    .ciphers(sslCiphers).build();
        }

    }

    if (callbackThreads == 0) {
        callbackExecutorQueue = new SynchronousQueue<Runnable>();
        callbackExecutor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
                callbackExecutorQueue, threadFactory);
    } else {
        callbackExecutorQueue = new LinkedBlockingQueue<Runnable>();
        callbackExecutor = new ThreadPoolExecutor(callbackThreads, callbackThreads, 0L, TimeUnit.MILLISECONDS,
                callbackExecutorQueue, threadFactory);
    }
    statsLogger.registerGauge("callbacksqueue", new Gauge<Integer>() {
        @Override
        public Integer getDefaultValue() {
            return 0;
        }

        @Override
        public Integer getSample() {
            return callbackExecutorQueue.size();
        }

    });
    InetSocketAddress address = new InetSocketAddress(host, port);
    LOGGER.log(Level.SEVERE, "Starting HerdDB network server at {0}:{1}", new Object[] { host, port + "" });
    if (address.isUnresolved()) {
        throw new IOException("Bind address " + host + ":" + port + " cannot be resolved");
    }
    ChannelInitializer<io.netty.channel.Channel> channelInitialized = new ChannelInitializer<io.netty.channel.Channel>() {
        @Override
        public void initChannel(io.netty.channel.Channel ch) throws Exception {
            NettyChannel session = new NettyChannel("unnamed", ch, callbackExecutor);
            if (acceptor != null) {
                acceptor.createConnection(session);
            }

            //                        ch.pipeline().addLast(new LoggingHandler());
            // Add SSL handler first to encrypt and decrypt everything.
            if (ssl) {
                ch.pipeline().addLast(sslCtx.newHandler(ch.alloc()));
            }

            ch.pipeline().addLast("lengthprepender", new LengthFieldPrepender(4));
            ch.pipeline().addLast("lengthbaseddecoder",
                    new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
            //                
            ch.pipeline().addLast("messagedecoder", new ProtocolMessageDecoder());
            ch.pipeline().addLast(new ServerInboundMessageHandler(session));
        }
    };
    if (enableRealNetwork) {
        if (NetworkUtils.isEnableEpoolNative()) {
            bossGroup = new EpollEventLoopGroup(workerThreads);
            workerGroup = new EpollEventLoopGroup(workerThreads);
            LOGGER.log(Level.FINE, "Using netty-native-epoll network type");
        } else {
            bossGroup = new NioEventLoopGroup(workerThreads);
            workerGroup = new NioEventLoopGroup(workerThreads);
            LOGGER.log(Level.FINE, "Using nio network type");
        }

        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup)
                .channel(NetworkUtils.isEnableEpoolNative() ? EpollServerSocketChannel.class
                        : NioServerSocketChannel.class)
                .childHandler(channelInitialized).option(ChannelOption.SO_BACKLOG, 128);
        ChannelFuture f = b.bind(address).sync();
        this.channel = f.channel();

    }

    if (enableJVMNetwork) {
        localBossGroup = new DefaultEventLoopGroup(workerThreads);
        localWorkerGroup = new DefaultEventLoopGroup(workerThreads);
        ServerBootstrap b_local = new ServerBootstrap();
        b_local.group(localBossGroup, localWorkerGroup).channel(LocalServerChannel.class)
                .childHandler(channelInitialized);

        String hostAddress = NetworkUtils.getAddress(address);
        LocalServerRegistry.registerLocalServer(hostAddress, port, ssl);

        ChannelFuture local_f = b_local.bind(new LocalAddress(hostAddress + ":" + port + ":" + ssl)).sync();
        this.local_channel = local_f.channel();
    }

}

From source file:hivemall.mix.server.MixServer.java

License:Open Source License

private void acceptConnections(@Nonnull MixServerInitializer initializer, int port)
        throws InterruptedException {
    final EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    final EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {/* w w  w. ja va 2  s .  c o m*/
        ServerBootstrap b = new ServerBootstrap();
        b.option(ChannelOption.SO_KEEPALIVE, true);
        b.group(bossGroup, workerGroup);
        b.channel(NioServerSocketChannel.class);
        b.handler(new LoggingHandler(LogLevel.INFO));
        b.childHandler(initializer);

        // Bind and start to accept incoming connections.
        ChannelFuture f = b.bind(port).sync();
        this.state = ServerState.RUNNING;

        // Wait until the server socket is closed.
        // In this example, this does not happen, but you can do that to gracefully
        // shut down your server.
        f.channel().closeFuture().sync();
    } finally {
        this.state = ServerState.STOPPING;
        workerGroup.shutdownGracefully();
        bossGroup.shutdownGracefully();
    }
}

From source file:holon.internal.http.netty.NettyEngine.java

License:Open Source License

@Override
public void serve(Supplier<Iterable<Route>> routes) {
    running = true;/*from  w w  w . ja va 2 s .c  om*/
    executor = Executors.newCachedThreadPool();

    disruptor = new Disruptor<>(NettyWorkEvent::new, 1024, executor);
    disruptor.handleEventsWithWorkerPool(createWorkers(workers, routes));
    disruptor.start();

    RingBuffer<NettyWorkEvent> ringBuffer = disruptor.getRingBuffer();

    bossGroup = new NioEventLoopGroup(1);
    workerGroup = new NioEventLoopGroup();

    ServerBootstrap b = new ServerBootstrap();
    b.group(bossGroup, workerGroup);
    b.channel(NioServerSocketChannel.class);
    b.childHandler(new Initializer(ringBuffer));

    try {
        b.bind(httpPort).sync();
    } catch (InterruptedException e) {
        throw new HolonException("Failed to bind to '" + httpPort + "', " + e.getMessage());
    }

}

From source file:httprestfulserver.HttpRESTfulServer.java

License:Apache License

public static void main(String[] args) throws Exception {
    // Configure SSL.
    final SslContext sslCtx;
    if (SSL) {/*from  w w  w .  j a va 2  s  .c  om*/
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
    } else {
        sslCtx = null;
    }

    // Configure the server.
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.option(ChannelOption.SO_BACKLOG, 1024);
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new HttpRESTfulServerInitializer(sslCtx));

        Channel ch = b.bind(PORT).sync().channel();

        System.err.println("Open your web browser and navigate to " + (SSL ? "https" : "http") + "://127.0.0.1:"
                + PORT + '/');

        ch.closeFuture().sync();
    } finally {
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
}

From source file:hws.channel.net.NetDeliver.java

License:Apache License

public void start() {
    super.start();

    try {//from www  . j  av  a  2 s  . c o m
        out = new PrintWriter(new BufferedWriter(
                new FileWriter("/home/hadoop/rcor/yarn/channel-deliver-" + channelName() + ".out")));
        out.println("Starting channel deliver: " + channelName() + " instance " + instanceId());
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    // Configure SSL.
    final SslContext sslCtx;
    if (SSL) {
        try {
            SelfSignedCertificate ssc = new SelfSignedCertificate();
            sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
        } catch (Exception e) {
            out.println("ERROR: " + e.getMessage());
            out.flush();
        }
    } else {
        sslCtx = null;
    }

    final ChannelDeliver deliverHandler = this;
    // Configure the server.
    EventLoopGroup bossGroup = new NioEventLoopGroup(1);
    EventLoopGroup workerGroup = new NioEventLoopGroup();
    try {
        ServerBootstrap b = new ServerBootstrap();
        b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100).handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline p = ch.pipeline();
                        if (sslCtx != null) {
                            p.addLast(sslCtx.newHandler(ch.alloc()));
                        }
                        //p.addLast(new LoggingHandler(LogLevel.INFO));
                        //p.addLast(new EchoServerHandler());
                        p.addLast(new ObjectEncoder(), new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                        p.addLast(new DefaultEventExecutorGroup(2), new NetDeliverHandler(deliverHandler));
                    }
                });

        out.println("Binding to a listening port");
        out.flush();
        // Start the server.
        ChannelFuture f = b.bind(0).sync();
        this.serverChannel = f.channel();
        this.latch = new CountDownLatch(1);

        SocketAddress socketAddress = this.serverChannel.localAddress();
        if (socketAddress instanceof InetSocketAddress) {
            out.println("Connected to port: " + ((InetSocketAddress) socketAddress).getPort());
            out.flush();
            shared().set("host-" + instanceId(), hws.net.NetUtil.getLocalCanonicalHostName());
            shared().set("port-" + instanceId(), new Integer(((InetSocketAddress) socketAddress).getPort()));
        }
        out.println("Host: " + hws.net.NetUtil.getLocalCanonicalHostName());
        out.println("Connected to: " + f.channel().localAddress().toString());
        out.flush();

        out.println("Running server, waiting for a close command");
        out.flush();
        // Wait until the server socket is closed.
        f.channel().closeFuture().sync();
        out.println("Channel closed");
        out.flush();
    } catch (Exception e) {
        out.println("ERROR: " + e.getMessage());
        out.flush();
    } finally {
        // Shut down all event loops to terminate all threads.
        bossGroup.shutdownGracefully();
        workerGroup.shutdownGracefully();
    }
    out.println("Counting down the latch");
    out.flush();
    this.latch.countDown();
}

From source file:io.advantageous.conekt.http.impl.HttpServerImpl.java

License:Open Source License

public synchronized HttpServer listen(int port, String host, Handler<AsyncResult<HttpServer>> listenHandler) {
    if (requestStream.handler() == null && wsStream.handler() == null) {
        throw new IllegalStateException("Set request or websocket handler first");
    }/*from www  .  ja  v a  2  s. c  om*/
    if (listening) {
        throw new IllegalStateException("Already listening");
    }
    listenContext = vertx.getOrCreateContext();
    listening = true;
    serverOrigin = (options.isSsl() ? "https" : "http") + "://" + host + ":" + port;
    synchronized (vertx.sharedHttpServers()) {
        id = new ServerID(port, host);
        HttpServerImpl shared = vertx.sharedHttpServers().get(id);
        if (shared == null) {
            serverChannelGroup = new DefaultChannelGroup("conekt-acceptor-channels",
                    GlobalEventExecutor.INSTANCE);
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(vertx.getAcceptorEventLoopGroup(), availableWorkers);
            bootstrap.channelFactory(new VertxNioServerChannelFactory());
            applyConnectionOptions(bootstrap);
            sslHelper.validate(vertx);
            bootstrap.childHandler(new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel ch) throws Exception {
                    if (requestStream.isPaused() || wsStream.isPaused()) {
                        ch.close();
                        return;
                    }
                    ChannelPipeline pipeline = ch.pipeline();
                    if (sslHelper.isSSL()) {
                        pipeline.addLast("ssl", sslHelper.createSslHandler(vertx, false));
                    }
                    pipeline.addLast("httpDecoder", new HttpRequestDecoder(options.getMaxInitialLineLength(),
                            options.getMaxHeaderSize(), options.getMaxChunkSize(), false));
                    pipeline.addLast("httpEncoder", new VertxHttpResponseEncoder());
                    if (options.isCompressionSupported()) {
                        pipeline.addLast("deflater", new HttpChunkContentCompressor());
                    }
                    if (sslHelper.isSSL() || options.isCompressionSupported()) {
                        // only add ChunkedWriteHandler when SSL is enabled otherwise it is not needed as FileRegion is used.
                        pipeline.addLast("chunkedWriter", new ChunkedWriteHandler()); // For large file / sendfile support
                    }
                    if (options.getIdleTimeout() > 0) {
                        pipeline.addLast("idle", new IdleStateHandler(0, 0, options.getIdleTimeout()));
                    }
                    pipeline.addLast("handler", new ServerHandler());
                }
            });

            addHandlers(this, listenContext);
            try {
                bindFuture = bootstrap.bind(new InetSocketAddress(InetAddress.getByName(host), port));
                Channel serverChannel = bindFuture.channel();
                serverChannelGroup.add(serverChannel);
                bindFuture.addListener(channelFuture -> {
                    if (!channelFuture.isSuccess()) {
                        vertx.sharedHttpServers().remove(id);
                    } else {
                        metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host),
                                options);
                    }
                });
            } catch (final Throwable t) {
                // Make sure we send the exception back through the handler (if any)
                if (listenHandler != null) {
                    vertx.runOnContext(v -> listenHandler.handle(Future.failedFuture(t)));
                } else {
                    // No handler - log so user can see failure
                    log.error("", t);
                }
                listening = false;
                return this;
            }
            vertx.sharedHttpServers().put(id, this);
            actualServer = this;
        } else {
            // Server already exists with that host/port - we will use that
            actualServer = shared;
            addHandlers(actualServer, listenContext);
            metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host), options);
        }
        actualServer.bindFuture.addListener(future -> {
            if (listenHandler != null) {
                final AsyncResult<HttpServer> res;
                if (future.isSuccess()) {
                    res = Future.succeededFuture(HttpServerImpl.this);
                } else {
                    res = Future.failedFuture(future.cause());
                    listening = false;
                }
                listenContext.runOnContext((v) -> listenHandler.handle(res));
            } else if (!future.isSuccess()) {
                listening = false;
                // No handler - log so user can see failure
                log.error("", future.cause());
            }
        });
    }
    return this;
}