public NettyClientServer(final Endpoint listenAddress, final SharedResources resources) {
this.listenAddress = listenAddress;
this.outstandingRequests = CacheBuilder.newBuilder()
.expireAfterAccess(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.build(FUTURE_LOADER);
this.resources = resources;
final Bootstrap clientBootstrap = new Bootstrap();
final RemovalListener<Endpoint, ChannelFuture> removalListener = removal ->
removal.getValue().channel().close()
.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
this.channelCache = CacheBuilder.newBuilder()
.expireAfterAccess(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS)
.removalListener(removalListener)
.build(new ClientChannelLoader(clientBootstrap));
final ClientHandler clientHandler = new ClientHandler();
clientBootstrap.group(resources.getEventLoopGroup())
.channel(NioSocketChannel.class)
.option(ChannelOption.SO_SNDBUF, 4096)
.option(ChannelOption.SO_RCVBUF, 4096)
.option(ChannelOption.SO_REUSEADDR, true)
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.handler(new ClientChannelInitializer(clientHandler));
}