Example usage for io.netty.channel ChannelOption WRITE_BUFFER_WATER_MARK

List of usage examples for io.netty.channel ChannelOption WRITE_BUFFER_WATER_MARK

Introduction

In this page you can find the example usage for io.netty.channel ChannelOption WRITE_BUFFER_WATER_MARK.

Prototype

ChannelOption WRITE_BUFFER_WATER_MARK

To view the source code for io.netty.channel ChannelOption WRITE_BUFFER_WATER_MARK.

Click Source Link

Usage

From source file:com.ibasco.agql.core.transport.NettyTransport.java

License:Open Source License

public NettyTransport(ChannelType channelType, ExecutorService executor) {
    executorService = executor;/*ww  w . ja  v  a2s .  com*/
    bootstrap = new Bootstrap();

    //Make sure we have a type set
    if (channelType == null)
        throw new IllegalStateException("No channel type has been specified");

    //Pick the proper event loop group
    if (eventLoopGroup == null) {
        eventLoopGroup = createEventLoopGroup(channelType);
    }

    //Default Channel Options
    addChannelOption(ChannelOption.ALLOCATOR, allocator);
    addChannelOption(ChannelOption.WRITE_BUFFER_WATER_MARK, WriteBufferWaterMark.DEFAULT);
    addChannelOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);

    //Set resource leak detection if debugging is enabled
    if (log.isDebugEnabled())
        ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.ADVANCED);

    //Initialize bootstrap
    bootstrap.group(eventLoopGroup).channel(channelType.getChannelClass());
}

From source file:com.mpush.core.server.ConnectionServer.java

License:Apache License

@Override
protected void initOptions(ServerBootstrap b) {
    super.initOptions(b);

    b.option(ChannelOption.SO_BACKLOG, 1024);

    /**//  w w w.j  ava2s  .co m
     * TCP????
     * NettyChannelOptionSO_SNDBUFSO_RCVBUF
     * ????????32K?
     */
    if (snd_buf.connect_server > 0)
        b.childOption(ChannelOption.SO_SNDBUF, snd_buf.connect_server);
    if (rcv_buf.connect_server > 0)
        b.childOption(ChannelOption.SO_RCVBUF, rcv_buf.connect_server);

    /**
     * ??????????
     * ???????????????
     * ????????
     * ????????
     * ??????
     * ???NettyChannelOutboundBuffer
     * buffernetty?channel write?buffer???????(?channelbuffer)
     * ??32(32?)32?
     * ?(?TCP??)
     * ??buffer???(?swap?linux killer)
     * ?channel?channel?active?
     *
     * ChannelOutboundBuffer????
     * buffer??channelisWritable??false
     * buffer??isWritable??trueisWritablefalse????
     * ???64K?32K???????
     */
    b.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK,
            new WriteBufferWaterMark(connect_server_low, connect_server_high));
}

From source file:com.mpush.core.server.GatewayServer.java

License:Apache License

@Override
protected void initOptions(ServerBootstrap b) {
    super.initOptions(b);
    if (snd_buf.gateway_server > 0)
        b.childOption(ChannelOption.SO_SNDBUF, snd_buf.gateway_server);
    if (rcv_buf.gateway_server > 0)
        b.childOption(ChannelOption.SO_RCVBUF, rcv_buf.gateway_server);
    /**//from w  w  w . j  a v a  2 s  .co  m
     * ??????????
     * ???????????????
     * ????????
     * ????????
     * ??????
     * ???NettyChannelOutboundBuffer
     * buffernetty?channel write?buffer???????(?channelbuffer)
     * ??32(32?)32?
     * ?(?TCP??)
     * ??buffer???(?swap?linux killer)
     * ?channel?channel?active?
     *
     * ChannelOutboundBuffer????
     * buffer??channelisWritable??false
     * buffer??isWritable??trueisWritablefalse????
     * ???64K?32K???????
     */
    if (gateway_server_low > 0 && gateway_server_high > 0) {
        b.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK,
                new WriteBufferWaterMark(gateway_server_low, gateway_server_high));
    }
}

From source file:com.navercorp.pinpoint.grpc.client.ChannelFactory.java

License:Apache License

private void setupClientOption(final NettyChannelBuilder channelBuilder) {
    channelBuilder.keepAliveTime(clientOption.getKeepAliveTime(), TimeUnit.MILLISECONDS);
    channelBuilder.keepAliveTimeout(clientOption.getKeepAliveTimeout(), TimeUnit.MILLISECONDS);
    channelBuilder.keepAliveWithoutCalls(clientOption.isKeepAliveWithoutCalls());
    channelBuilder.maxHeaderListSize(clientOption.getMaxHeaderListSize());
    channelBuilder.maxInboundMessageSize(clientOption.getMaxInboundMessageSize());

    // ChannelOption
    channelBuilder.withOption(ChannelOption.TCP_NODELAY, true);
    channelBuilder.withOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, clientOption.getConnectTimeout());
    final WriteBufferWaterMark writeBufferWaterMark = new WriteBufferWaterMark(
            clientOption.getWriteBufferLowWaterMark(), clientOption.getWriteBufferHighWaterMark());
    channelBuilder.withOption(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark);
    if (logger.isInfoEnabled()) {
        logger.info("Set clientOption {}. name={}", clientOption, name);
    }/*from  w w w . j av  a  2  s.co  m*/
}

From source file:com.navercorp.pinpoint.grpc.server.ServerFactory.java

License:Apache License

private void setupServerOption(final NettyServerBuilder builder) {
    // TODO @see PinpointServerAcceptor
    builder.withChildOption(ChannelOption.TCP_NODELAY, true);
    builder.withChildOption(ChannelOption.SO_REUSEADDR, true);
    builder.withChildOption(ChannelOption.SO_RCVBUF, this.serverOption.getReceiveBufferSize());
    builder.withChildOption(ChannelOption.SO_BACKLOG, this.serverOption.getBacklogQueueSize());
    builder.withChildOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.serverOption.getConnectTimeout());
    final WriteBufferWaterMark writeBufferWaterMark = new WriteBufferWaterMark(
            this.serverOption.getWriteBufferLowWaterMark(), this.serverOption.getWriteBufferHighWaterMark());
    builder.withChildOption(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark);

    builder.handshakeTimeout(this.serverOption.getHandshakeTimeout(), TimeUnit.MILLISECONDS);
    builder.flowControlWindow(this.serverOption.getFlowControlWindow());

    builder.maxInboundMessageSize(this.serverOption.getMaxInboundMessageSize());
    builder.maxHeaderListSize(this.serverOption.getMaxHeaderListSize());

    builder.keepAliveTime(this.serverOption.getKeepAliveTime(), TimeUnit.MILLISECONDS);
    builder.keepAliveTimeout(this.serverOption.getKeepAliveTimeout(), TimeUnit.MILLISECONDS);
    builder.permitKeepAliveTime(this.serverOption.getPermitKeepAliveTimeout(), TimeUnit.MILLISECONDS);
    builder.permitKeepAliveWithoutCalls(this.serverOption.isPermitKeepAliveWithoutCalls());

    builder.maxConnectionIdle(this.serverOption.getMaxConnectionIdle(), TimeUnit.MILLISECONDS);
    builder.maxConnectionAge(this.serverOption.getMaxConnectionAge(), TimeUnit.MILLISECONDS);
    builder.maxConnectionAgeGrace(this.serverOption.getMaxConnectionAgeGrace(), TimeUnit.MILLISECONDS);
    builder.maxConcurrentCallsPerConnection(this.serverOption.getMaxConcurrentCallsPerConnection());
    if (logger.isInfoEnabled()) {
        logger.info("Set serverOption {}. name={}, hostname={}, port={}", serverOption, name, hostname, port);
    }//from w  w  w . ja va  2  s. co m
}

From source file:com.relayrides.pushy.apns.ApnsClient.java

License:Open Source License

/**
 * Sets the buffer usage watermark range for this client. When a the amount of buffered and not-yet-flushed data in
 * the client's network channel exceeds the given "high-water" mark, the channel will begin rejecting new data until
 * enough data has been flushed to cross the given "low-water" mark. Notifications sent when the client's network
 * channel is "flooded" will fail with a {@link ClientBusyException}.
 *
 * @param writeBufferWatermark the buffer usage watermark range for the client's network channel
 *
 * @since 0.8.2//from w w w .  j a v a 2 s.com
 */
protected void setChannelWriteBufferWatermark(final WriteBufferWaterMark writeBufferWaterMark) {
    synchronized (this.bootstrap) {
        this.bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK, writeBufferWaterMark);
    }
}

From source file:com.tc.websocket.server.DominoWebSocketServer.java

License:Apache License

@Override
public synchronized void start() {

    if (this.isOn())
        return;//from   w ww .j a v  a 2  s. c o  m

    try {
        try {

            ServerBootstrap boot = new ServerBootstrap();

            if (cfg.isNativeTransport()) {
                boot.channel(EpollServerSocketChannel.class);
            } else {
                boot.channel(NioServerSocketChannel.class);
            }

            boot.group(bossGroup, workerGroup).option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                    .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK,
                            new WriteBufferWaterMark(8 * 1024, 32 * 1024))
                    .childOption(ChannelOption.SO_SNDBUF, cfg.getSendBuffer())
                    .childOption(ChannelOption.SO_RCVBUF, cfg.getReceiveBuffer())
                    .childOption(ChannelOption.TCP_NODELAY, true).childHandler(init);

            //bind to the main port
            boot.bind(cfg.getPort()).sync();

            //bind to the redirect port (e.g. 80 will redirect to 443)
            for (Integer port : cfg.getRedirectPorts()) {
                ChannelFuture f = boot.bind(port);
                f.sync();
            }

            this.on.set(true);

            String version = BundleUtils.getVersion(Activator.bundle);
            String name = BundleUtils.getName(Activator.bundle);
            cfg.print(name + " ready and listening on " + cfg.getPort() + " running version " + version);

        } finally {

        }
    } catch (Exception e) {
        LOG.log(Level.SEVERE, null, e);
    }
}

From source file:dorkbox.network.Client.java

License:Apache License

/**
 * Starts a REMOTE <b>only</b> client, which will connect to the specified host using the specified Connections Options
 *///from ww w  .jav  a2 s.c o  m
@SuppressWarnings("AutoBoxing")
public Client(final Configuration config) throws SecurityException {
    super(config);

    String threadName = Client.class.getSimpleName();

    this.config = config;
    boolean hostConfigured = (config.tcpPort > 0 || config.udpPort > 0) && config.host != null;
    boolean isLocalChannel = config.localChannelName != null;

    if (isLocalChannel && hostConfigured) {
        String msg = threadName
                + " Local channel use and TCP/UDP use are MUTUALLY exclusive. Unable to determine what to do.";
        logger.error(msg);
        throw new IllegalArgumentException(msg);
    }

    localChannelName = config.localChannelName;
    hostName = config.host;

    Bootstrap localBootstrap = null;
    Bootstrap tcpBootstrap = null;
    Bootstrap udpBootstrap = null;

    if (config.localChannelName != null) {
        localBootstrap = new Bootstrap();
    }

    if (config.tcpPort > 0 || config.udpPort > 0) {
        if (config.host == null) {
            throw new IllegalArgumentException("You must define what host you want to connect to.");
        }

        if (config.host.equals("0.0.0.0")) {
            throw new IllegalArgumentException(
                    "You cannot connect to 0.0.0.0, you must define what host you want to connect to.");
        }
    }

    if (config.tcpPort > 0) {
        tcpBootstrap = new Bootstrap();
    }

    if (config.udpPort > 0) {
        udpBootstrap = new Bootstrap();
    }

    if (localBootstrap == null && tcpBootstrap == null && udpBootstrap == null) {
        throw new IllegalArgumentException(
                "You must define how you want to connect, either LOCAL channel name, TCP port, or UDP port");
    }

    if (config.localChannelName != null) {
        // no networked bootstraps. LOCAL connection only

        bootstraps.add(new BootstrapWrapper("LOCAL", config.localChannelName, -1, localBootstrap));

        localBootstrap.group(newEventLoop(LOCAL, 1, threadName + "-JVM-BOSS")).channel(LocalChannel.class)
                .remoteAddress(new LocalAddress(config.localChannelName))
                .handler(new RegistrationLocalHandlerClient(threadName, registrationWrapper));
    }

    EventLoopGroup workerEventLoop = null;
    if (tcpBootstrap != null || udpBootstrap != null) {
        workerEventLoop = newEventLoop(config.workerThreadPoolSize, threadName);
    }

    if (tcpBootstrap != null) {
        bootstraps.add(new BootstrapWrapper("TCP", config.host, config.tcpPort, tcpBootstrap));

        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            tcpBootstrap.channel(OioSocketChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            tcpBootstrap.channel(EpollSocketChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            tcpBootstrap.channel(KQueueSocketChannel.class);
        } else {
            tcpBootstrap.channel(NioSocketChannel.class);
        }

        tcpBootstrap.group(newEventLoop(1, threadName + "-TCP-BOSS"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .remoteAddress(config.host, config.tcpPort).handler(new RegistrationRemoteHandlerClientTCP(
                        threadName, registrationWrapper, workerEventLoop));

        // android screws up on this!!
        tcpBootstrap.option(ChannelOption.TCP_NODELAY, !OS.isAndroid()).option(ChannelOption.SO_KEEPALIVE,
                true);
    }

    if (udpBootstrap != null) {
        bootstraps.add(new BootstrapWrapper("UDP", config.host, config.udpPort, udpBootstrap));

        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            udpBootstrap.channel(OioDatagramChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            udpBootstrap.channel(EpollDatagramChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            udpBootstrap.channel(KQueueDatagramChannel.class);
        } else {
            udpBootstrap.channel(NioDatagramChannel.class);
        }

        udpBootstrap.group(newEventLoop(1, threadName + "-UDP-BOSS"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                // Netty4 has a default of 2048 bytes as upper limit for datagram packets.
                .option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(EndPoint.udpMaxSize))
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .localAddress(new InetSocketAddress(0)) // bind to wildcard
                .remoteAddress(new InetSocketAddress(config.host, config.udpPort))
                .handler(new RegistrationRemoteHandlerClientUDP(threadName, registrationWrapper,
                        workerEventLoop));

        // Enable to READ and WRITE MULTICAST data (ie, 192.168.1.0)
        // in order to WRITE: write as normal, just make sure it ends in .255
        // in order to LISTEN:
        //    InetAddress group = InetAddress.getByName("203.0.113.0");
        //    NioDatagramChannel.joinGroup(group);
        // THEN once done
        //    NioDatagramChannel.leaveGroup(group), close the socket
        udpBootstrap.option(ChannelOption.SO_BROADCAST, false).option(ChannelOption.SO_SNDBUF, udpMaxSize);
    }
}

From source file:dorkbox.network.Server.java

License:Apache License

/**
 * Convenience method to starts a server with the specified Connection Options
 *//*  www. j  a  v  a 2  s  .  co m*/
@SuppressWarnings("AutoBoxing")
public Server(Configuration config) throws SecurityException {
    // watch-out for serialization... it can be NULL incoming. The EndPoint (superclass) sets it, if null, so
    // you have to make sure to use this.serialization
    super(config);

    tcpPort = config.tcpPort;
    udpPort = config.udpPort;

    localChannelName = config.localChannelName;

    if (config.host == null) {
        // we set this to "0.0.0.0" so that it is clear that we are trying to bind to that address.
        hostName = "0.0.0.0";

        // make it clear that this is what we do (configuration wise) so that variable examination is consistent
        config.host = hostName;
    } else {
        hostName = config.host;
    }

    if (localChannelName != null) {
        localBootstrap = new ServerBootstrap();
    } else {
        localBootstrap = null;
    }

    if (tcpPort > 0) {
        tcpBootstrap = new ServerBootstrap();
    } else {
        tcpBootstrap = null;
    }

    if (udpPort > 0) {
        // This is what allows us to have UDP behave "similar" to TCP, in that a session is established based on the port/ip of the
        // remote connection. This allows us to reuse channels and have "state" for a UDP connection that normally wouldn't exist.
        // Additionally, this is what responds to discovery broadcast packets
        udpBootstrap = new SessionBootstrap(tcpPort, udpPort);
    } else {
        udpBootstrap = null;
    }

    String threadName = Server.class.getSimpleName();

    // always use local channels on the server.
    if (localBootstrap != null) {
        localBootstrap
                .group(newEventLoop(LOCAL, 1, threadName + "-JVM-BOSS"), newEventLoop(LOCAL, 1, threadName))
                .channel(LocalServerChannel.class)
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))
                .localAddress(new LocalAddress(localChannelName))
                .childHandler(new RegistrationLocalHandlerServer(threadName, registrationWrapper));
    }

    EventLoopGroup workerEventLoop = null;
    if (tcpBootstrap != null || udpBootstrap != null) {
        workerEventLoop = newEventLoop(config.workerThreadPoolSize, threadName);
    }

    if (tcpBootstrap != null) {
        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            tcpBootstrap.channel(OioServerSocketChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            tcpBootstrap.channel(EpollServerSocketChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            tcpBootstrap.channel(KQueueServerSocketChannel.class);
        } else {
            tcpBootstrap.channel(NioServerSocketChannel.class);
        }

        // TODO: If we use netty for an HTTP server,
        // Beside the usual ChannelOptions the Native Transport allows to enable TCP_CORK which may come in handy if you implement a HTTP Server.

        tcpBootstrap
                .group(newEventLoop(1, threadName + "-TCP-BOSS"),
                        newEventLoop(1, threadName + "-TCP-REGISTRATION"))
                .option(ChannelOption.SO_BACKLOG, backlogConnectionCount)
                .option(ChannelOption.SO_REUSEADDR, true)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))

                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new RegistrationRemoteHandlerServerTCP(threadName, registrationWrapper,
                        workerEventLoop));

        // have to check options.host for "0.0.0.0". we don't bind to "0.0.0.0", we bind to "null" to get the "any" address!
        if (hostName.equals("0.0.0.0")) {
            tcpBootstrap.localAddress(tcpPort);
        } else {
            tcpBootstrap.localAddress(hostName, tcpPort);
        }

        // android screws up on this!!
        tcpBootstrap.option(ChannelOption.TCP_NODELAY, !OS.isAndroid()).childOption(ChannelOption.TCP_NODELAY,
                !OS.isAndroid());
    }

    if (udpBootstrap != null) {
        if (OS.isAndroid()) {
            // android ONLY supports OIO (not NIO)
            udpBootstrap.channel(OioDatagramChannel.class);
        } else if (OS.isLinux() && NativeLibrary.isAvailable()) {
            // epoll network stack is MUCH faster (but only on linux)
            udpBootstrap.channel(EpollDatagramChannel.class);
        } else if (OS.isMacOsX() && NativeLibrary.isAvailable()) {
            // KQueue network stack is MUCH faster (but only on macosx)
            udpBootstrap.channel(KQueueDatagramChannel.class);
        } else {
            // windows and linux/mac that are incompatible with the native implementations
            udpBootstrap.channel(NioDatagramChannel.class);
        }

        // Netty4 has a default of 2048 bytes as upper limit for datagram packets, we want this to be whatever we specify
        FixedRecvByteBufAllocator recvByteBufAllocator = new FixedRecvByteBufAllocator(EndPoint.udpMaxSize);

        udpBootstrap
                .group(newEventLoop(1, threadName + "-UDP-BOSS"),
                        newEventLoop(1, threadName + "-UDP-REGISTRATION"))
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .option(ChannelOption.RCVBUF_ALLOCATOR, recvByteBufAllocator)
                .option(ChannelOption.WRITE_BUFFER_WATER_MARK,
                        new WriteBufferWaterMark(WRITE_BUFF_LOW, WRITE_BUFF_HIGH))

                // a non-root user can't receive a broadcast packet on *nix if the socket is bound on non-wildcard address.
                // TODO: move broadcast to it's own handler, and have UDP server be able to be bound to a specific IP
                // OF NOTE: At the end in my case I decided to bind to .255 broadcast address on Linux systems. (to receive broadcast packets)
                .localAddress(udpPort) // if you bind to a specific interface, Linux will be unable to receive broadcast packets! see: http://developerweb.net/viewtopic.php?id=5722
                .childHandler(new RegistrationRemoteHandlerServerUDP(threadName, registrationWrapper,
                        workerEventLoop));

        // // have to check options.host for null. we don't bind to 0.0.0.0, we bind to "null" to get the "any" address!
        // if (hostName.equals("0.0.0.0")) {
        //     udpBootstrap.localAddress(hostName, tcpPort);
        // }
        // else {
        //     udpBootstrap.localAddress(udpPort);
        // }

        // Enable to READ from MULTICAST data (ie, 192.168.1.0)
        // in order to WRITE: write as normal, just make sure it ends in .255
        // in order to LISTEN:
        //    InetAddress group = InetAddress.getByName("203.0.113.0");
        //    socket.joinGroup(group);
        // THEN once done
        //    socket.leaveGroup(group), close the socket
        // Enable to WRITE to MULTICAST data (ie, 192.168.1.0)
        udpBootstrap.option(ChannelOption.SO_BROADCAST, false).option(ChannelOption.SO_SNDBUF, udpMaxSize);
    }
}

From source file:io.atomix.cluster.messaging.impl.NettyMessagingService.java

License:Apache License

private Bootstrap bootstrapClient(Address address) {
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    bootstrap.option(ChannelOption.WRITE_BUFFER_WATER_MARK,
            new WriteBufferWaterMark(10 * 32 * 1024, 10 * 64 * 1024));
    bootstrap.option(ChannelOption.SO_RCVBUF, 1024 * 1024);
    bootstrap.option(ChannelOption.SO_SNDBUF, 1024 * 1024);
    bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
    bootstrap.option(ChannelOption.TCP_NODELAY, true);
    bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000);
    bootstrap.group(clientGroup);/*from   ww w  .  j  av  a 2  s.  c  om*/
    // TODO: Make this faster:
    // http://normanmaurer.me/presentations/2014-facebook-eng-netty/slides.html#37.0
    bootstrap.channel(clientChannelClass);
    bootstrap.remoteAddress(address.address(true), address.port());
    if (enableNettyTls) {
        bootstrap.handler(new SslClientCommunicationChannelInitializer());
    } else {
        bootstrap.handler(new BasicChannelInitializer());
    }
    return bootstrap;
}