protected Client createClient(String targetIP, int targetPort, int connectTimeout, String key) throws Exception { if (connectTimeout < 1000) { bootstrap.setOption("connectTimeoutMillis", 1000); } else { bootstrap.setOption("connectTimeoutMillis", connectTimeout); } NettyClientHandler handler = new NettyClientHandler(this, key); bootstrap.setPipelineFactory(new NettyClientPipelineFactory(handler)); ChannelFuture future = bootstrap.connect(new InetSocketAddress(targetIP, targetPort)); future.awaitUninterruptibly(connectTimeout); if (!future.isDone()) { LOGGER.error("Create connection to " + targetIP + ":" + targetPort + " timeout!"); throw new Exception("Create connection to " + targetIP + ":" + targetPort + " timeout!"); } if (future.isCancelled()) { LOGGER.error("Create connection to " + targetIP + ":" + targetPort + " cancelled by user!"); throw new Exception( "Create connection to " + targetIP + ":" + targetPort + " cancelled by user!"); } if (!future.isSuccess()) { LOGGER.error( "Create connection to " + targetIP + ":" + targetPort + " error", future.getCause()); throw new Exception( "Create connection to " + targetIP + ":" + targetPort + " error", future.getCause()); } NettyClient client = new NettyClient(future, key, connectTimeout); handler.setClient(client); return client; }
public static void main(String[] args) throws Exception { String host = "localhost"; int port = Integer.parseInt("8080"); ChannelFactory factory = new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ClientBootstrap bootstrap = new ClientBootstrap(factory); bootstrap.setPipelineFactory( new ChannelPipelineFactory() { public ChannelPipeline getPipeline() { return Channels.pipeline(new TimeDecoder(), new TimeClientHandler()); } }); bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("keepAlive", true); ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); future.awaitUninterruptibly(); if (!future.isSuccess()) { future.getCause().printStackTrace(); } future.getChannel().getCloseFuture().awaitUninterruptibly(); factory.releaseExternalResources(); }
/** Connects to the IMAP server logs in with the given credentials. */ @Override public synchronized boolean connect(final DisconnectListener listener) { reset(); ChannelFuture future = bootstrap.connect(new InetSocketAddress(config.getHost(), config.getPort())); Channel channel = future.awaitUninterruptibly().getChannel(); if (!future.isSuccess()) { throw new RuntimeException("Could not connect channel", future.getCause()); } this.channel = channel; this.disconnectListener = listener; if (null != listener) { // https://issues.jboss.org/browse/NETTY-47?page=com.atlassian.jirafisheyeplugin%3Afisheye-issuepanel#issue-tabs channel .getCloseFuture() .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { mailClientHandler.idleAcknowledged.set(false); mailClientHandler.disconnected(); listener.disconnected(); } }); } return login(); }
public void operationComplete(ChannelFuture closeNotifyFuture) throws Exception { if (!(closeNotifyFuture.getCause() instanceof ClosedChannelException)) { Channels.close(context, e.getFuture()); } else { e.getFuture().setSuccess(); } }
protected void init() { // Configure the client. bootstrap = new ClientBootstrap( new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); // Set up the event pipeline factory. bootstrap.setPipelineFactory(new FileClientPipelineFactory()); // Options for a new channel bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("receiveBufferSize", 1048576); ChannelFuture future = bootstrap.connect(new InetSocketAddress("localhost", 8022)); // Wait until the connection is made successfully. future.awaitUninterruptibly(timeout); future.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { System.out.println("Connected."); } }); if (!future.isSuccess()) { future.getCause().printStackTrace(); bootstrap.releaseExternalResources(); return; } channel = future.getChannel(); }
public void stop() { log.info("Shutting down proxy"); if (stopped.get()) { log.info("Already stopped"); return; } stopped.set(true); log.info("Closing all channels..."); // See http://static.netty.io/3.5/guide/#start.12 final ChannelGroupFuture future = allChannels.close(); future.awaitUninterruptibly(10 * 1000); if (!future.isCompleteSuccess()) { final Iterator<ChannelFuture> iter = future.iterator(); while (iter.hasNext()) { final ChannelFuture cf = iter.next(); if (!cf.isSuccess()) { log.warn("Cause of failure for {} is {}", cf.getChannel(), cf.getCause()); } } } log.info("Stopping timer"); timer.stop(); serverChannelFactory.releaseExternalResources(); clientChannelFactory.releaseExternalResources(); log.info("Done shutting down proxy"); }
public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { return; } if (request.getMessageType() != Constants.MESSAGE_TYPE_HEART) { connected = false; } InvocationResponse response = ProviderUtils.createFailResponse(request, future.getCause()); processResponse(response); }
@Override public void connect() throws NntpClientConnectionError { // We'll be waiting for the connection message. NntpFuture<GenericResponse> welcomeFuture = new NntpFuture<>(Response.ResponseType.WELCOME); this.pipeline.add(welcomeFuture); // Connect to the server now. ChannelFuture future = this.initializeChannel(new InetSocketAddress(this.host, this.port)); if (!future.isSuccess()) { throw new NntpClientConnectionError(future.getCause()); } this.channel = future.getChannel(); if (this.ssl) { ChannelFuture handshakeFuture = this.channel.getPipeline().get(SslHandler.class).handshake().awaitUninterruptibly(); if (!handshakeFuture.isSuccess()) { throw new NntpClientConnectionError(handshakeFuture.getCause()); } } GenericResponse response = Futures.getUnchecked(welcomeFuture); boolean temporarilyUnavailable = false; switch (response.getCode()) { case 200: this.canPost = true; case 201: return; case 400: temporarilyUnavailable = true; case 502: throw new NntpClientConnectionError( new NntpServerUnavailableException(temporarilyUnavailable)); default: // FIXME: typed exception here mebbe? throw new NntpClientConnectionError( new RuntimeException( "Unexpected status code " + response.getCode() + " returned on initial connection.")); } }
public void close() throws IOException { ChannelGroupFuture f = group.close().awaitUninterruptibly(); if (!f.isCompleteSuccess()) { for (ChannelFuture future : f) { if (!future.isSuccess()) { throw new IOException(future.getCause()); } } } bootstrap.releaseExternalResources(); }
@Override public void operationComplete(ChannelFuture cf) throws Exception { if (!cf.isSuccess()) { synchronized (connections) { NodeConnection c = connections.remove(node.getNodeId()); if (c != null) c.nuke(); cf.getChannel().close(); } String message = "[unknown error]"; if (cf.isCancelled()) message = "Timed out on connect"; if (cf.getCause() != null) message = cf.getCause().getMessage(); logger.debug( "[{}->{}] Could not connect to RPC " + "node: {}", new Object[] {syncManager.getLocalNodeId(), node.getNodeId(), message}); } else { logger.trace( "[{}->{}] Channel future successful", syncManager.getLocalNodeId(), node.getNodeId()); } }
public static ControlMessage capiInvoke(RemoteCapi remoteCapi, ControlMessage request) throws CapiException { InOutClientHandler inOut = null; ClientBootstrap bootstrap = null; try { // configure client bootstrap Executor executor = Executors.newCachedThreadPool(); bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(executor, executor)); // use Request-Response handler business logic inOut = new InOutClientHandler(request); bootstrap.setPipelineFactory(new RemoteCapiPipelineFactory(inOut)); // start the connection attempt ChannelFuture future = bootstrap.connect(remoteCapi.getRemoteAddress()); // wait until the connection is closed or the connection attempt // fails future.getChannel().getCloseFuture().await(IN_OUT_TIMEOUT_SECONDS, TimeUnit.SECONDS); // in event of connection failure, throw an exception if (future.getCause() != null) { throw new CapiException(Info.EXCHANGE_RESOURCE_ERROR, future.getCause().getMessage()); } } catch (InterruptedException e) { return null; } finally { // shut down thread pools to exit bootstrap.releaseExternalResources(); } return inOut.getOut(); }
@Override public void operationComplete(ChannelFuture channelFuture) throws Exception { if (channelFuture.isSuccess()) { channel = channelFuture.getChannel(); channelWriteFuture = channelFuture.getChannel().write(httpRequest); channelWriteFuture.addListener(ChannelFutureListener.CLOSE); LOG.debug("Sending configuration info to: " + channel.getRemoteAddress()); LOG.info("Greetings to: " + channel.getRemoteAddress()); } else { LOG.warn( "Failed to connect to heartbeat service at " + remoteAddr + ": " + channelFuture.getCause().getMessage()); if (channel != null) { channel.close(); } } }
public void connect( String id, String host, int port, int keepAlive, String username, String password) { try { bootstrap = new ClientBootstrap( new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); handler = new MqttMessageHandler(); handler.setListener(listener); bootstrap.setPipelineFactory( new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline(new MqttMessageEncoder(), new MqttMessageDecoder(), handler); } }); bootstrap.setOption("tcpNoDelay", true); bootstrap.setOption("keepAlive", true); ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); channel = future.awaitUninterruptibly().getChannel(); if (!future.isSuccess()) { future.getCause().printStackTrace(); bootstrap.releaseExternalResources(); return; } ConnectMessage cm = new ConnectMessage(id, true, keepAlive); if (username != null && password != null) { cm.setCredentials(username, password); } channel.write(cm); establishKeepAlive(keepAlive); // TODO: Should probably wait for the ConnAck message } catch (Exception e) { e.printStackTrace(); } }
private <K, V, T extends RedisAsyncConnection<K, V>> T connect( CommandHandler<K, V> handler, T connection) { try { ConnectionWatchdog watchdog = new ConnectionWatchdog(bootstrap, channels, timer); ChannelPipeline pipeline = Channels.pipeline(watchdog, handler, connection); Channel channel = bootstrap.getFactory().newChannel(pipeline); ChannelFuture future = channel.connect((SocketAddress) bootstrap.getOption("remoteAddress")); future.await(); if (!future.isSuccess()) { throw future.getCause(); } watchdog.setReconnect(true); return connection; } catch (Throwable e) { throw new RedisException("Unable to connect", e); } }
public File get() throws IOException { ClientBootstrap bootstrap = new ClientBootstrap( new NioClientSocketChannelFactory( Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); bootstrap.setOption("connectTimeoutMillis", 5000L); // set 5 sec bootstrap.setOption("receiveBufferSize", 1048576); // set 1M ChannelPipelineFactory factory = new HttpClientPipelineFactory(file); bootstrap.setPipelineFactory(factory); ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port)); // Wait until the connection attempt succeeds or fails. Channel channel = future.awaitUninterruptibly().getChannel(); if (!future.isSuccess()) { bootstrap.releaseExternalResources(); throw new IOException(future.getCause()); } String query = uri.getPath() + (uri.getQuery() != null ? "?" + uri.getQuery() : ""); // Prepare the HTTP request. HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, query); request.setHeader(HttpHeaders.Names.HOST, host); LOG.info("Fetch: " + request.getUri()); request.setHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); request.setHeader(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); // Send the HTTP request. channel.write(request); // Wait for the server to close the connection. channel.getCloseFuture().awaitUninterruptibly(); // Shut down executor threads to exit. bootstrap.releaseExternalResources(); return file; }
/** * Writes the given body to Netty channel. Will wait until the body has been written. * * @param channel the Netty channel * @param remoteAddress the remote address when using UDP * @param body the body to write (send) * @param exchange the exchange * @throws CamelExchangeException is thrown if the body could not be written for some reasons (eg * remote connection is closed etc.) */ public static void writeBodySync( Channel channel, SocketAddress remoteAddress, Object body, Exchange exchange) throws CamelExchangeException { // the write operation is asynchronous. Use future to wait until the session has been written ChannelFuture future; if (remoteAddress != null) { future = channel.write(body, remoteAddress); } else { future = channel.write(body); } // wait for the write if (LOG.isTraceEnabled()) { LOG.trace("Waiting for write to complete"); } future.awaitUninterruptibly(); // if it was not a success then thrown an exception if (!future.isSuccess()) { LOG.warn("Cannot write body: " + body + " using channel: " + channel); throw new CamelExchangeException("Cannot write body", exchange, future.getCause()); } }
@Override public void operationComplete(ChannelFuture future) throws Exception { // if it was not a success then thrown an exception if (!future.isSuccess()) { Exception e = new CamelExchangeException( "Cannot write response to " + remoteAddress, exchange, future.getCause()); consumer.getExceptionHandler().handleException(e); } // should channel be closed after complete? Boolean close; if (exchange.hasOut()) { close = exchange .getOut() .getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class); } else { close = exchange .getIn() .getHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, Boolean.class); } // should we disconnect, the header can override the configuration boolean disconnect = consumer.getConfiguration().isDisconnect(); if (close != null) { disconnect = close; } if (disconnect) { if (LOG.isTraceEnabled()) { LOG.trace("Closing channel when complete at address: {}", remoteAddress); } NettyHelper.close(future.getChannel()); } }
/** * Wait for the client to be connected (Passive) or Wait for the server to be connected to the * client (Active) * * @return True if the connection is OK * @throws Reply425Exception */ public boolean openDataConnection() throws Reply425Exception { // Prepare this Data channel to be closed ;-) // In fact, prepare the future close op which should occur since it is // now opened closedDataChannel = new WaarpFuture(true); FtpDataAsyncConn dataAsyncConn = session.getDataConn(); if (!dataAsyncConn.isStreamFile()) { // FIXME isConnected or isDNHReady ? if (dataAsyncConn.isConnected()) { // Already connected // logger.debug("Connection already open"); session.setReplyCode( ReplyCode.REPLY_125_DATA_CONNECTION_ALREADY_OPEN, dataAsyncConn.getType().name() + " mode data connection already open"); return true; } } else { // Stream, Data Connection should not be opened if (dataAsyncConn.isConnected()) { logger.error("Connection already open but should not since in Stream mode"); setTransferAbortedFromInternal(false); throw new Reply425Exception("Connection already open but should not since in Stream mode"); } } // Need to open connection session.setReplyCode( ReplyCode.REPLY_150_FILE_STATUS_OKAY, "Opening " + dataAsyncConn.getType().name() + " mode data connection"); if (dataAsyncConn.isPassiveMode()) { if (!dataAsyncConn.isBind()) { // No passive connection prepared throw new Reply425Exception("No passive data connection prepared"); } // Wait for the connection to be done by the client // logger.debug("Passive mode standby"); try { dataChannel = waitForOpenedDataChannel(); dataAsyncConn.setNewOpenedDataChannel(dataChannel); } catch (InterruptedException e) { logger.warn("Connection abort in passive mode", e); // Cannot open connection throw new Reply425Exception("Cannot open passive data connection"); } // logger.debug("Passive mode connected"); } else { // Wait for the server to be connected to the client InetAddress inetAddress = dataAsyncConn.getLocalAddress().getAddress(); InetSocketAddress inetSocketAddress = dataAsyncConn.getRemoteAddress(); if (session .getConfiguration() .getFtpInternalConfiguration() .hasFtpSession(inetAddress, inetSocketAddress)) { throw new Reply425Exception( "Cannot open active data connection since remote address is already in use: " + inetSocketAddress); } // logger.debug("Active mode standby"); ClientBootstrap clientBootstrap = session .getConfiguration() .getFtpInternalConfiguration() .getActiveBootstrap(session.isDataSsl()); session.getConfiguration().setNewFtpSession(inetAddress, inetSocketAddress, session); // Set the session for the future dataChannel String mylog = session.toString(); logger.debug( "DataConn for: " + session.getCurrentCommand().getCommand() + " to " + inetSocketAddress.toString()); ChannelFuture future = clientBootstrap.connect(inetSocketAddress, dataAsyncConn.getLocalAddress()); try { future.await(); } catch (InterruptedException e1) { } if (!future.isSuccess()) { logger.warn( "Connection abort in active mode from future while session: " + session.toString() + "\nTrying connect to: " + inetSocketAddress.toString() + "\nWas: " + mylog, future.getCause()); // Cannot open connection session.getConfiguration().delFtpSession(inetAddress, inetSocketAddress); throw new Reply425Exception("Cannot open active data connection"); } try { dataChannel = waitForOpenedDataChannel(); dataAsyncConn.setNewOpenedDataChannel(dataChannel); } catch (InterruptedException e) { logger.warn("Connection abort in active mode", e); // Cannot open connection session.getConfiguration().delFtpSession(inetAddress, inetSocketAddress); throw new Reply425Exception("Cannot open active data connection"); } // logger.debug("Active mode connected"); } if (dataChannel == null) { // Cannot have a new Data connection since shutdown if (!dataAsyncConn.isPassiveMode()) { session .getConfiguration() .getFtpInternalConfiguration() .delFtpSession( dataAsyncConn.getLocalAddress().getAddress(), dataAsyncConn.getRemoteAddress()); } throw new Reply425Exception("Cannot open data connection, shuting down"); } return true; }
/** * Start a HyperGateClient * * <p>for that case use * * @throws Exception */ @Override public void start() throws Exception { if (this.running) { throw new InstantiationException("HyperGate client " + this.getName() + "is running"); } // Configure the client. // TODO make it more robust & speedy implements Kryo serializer this.channelFactory = new NioClientSocketChannelFactory( // TODO implement other executors Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); this.clientBootstrap = new ClientBootstrap(channelFactory); ChannelPipelineFactory channelPipelineFactory = new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { return Channels.pipeline( // TODO make Encoder & Decoder - like a Strategy Pattern, and changeable via // external settings // new KryoObjectEncoder(), // new // KryoObjectDecoder(ClassResolvers.cacheDisabled(getClass().getClassLoader())) // TODO #6 new ObjectEncoder(), new ObjectDecoder(ClassResolvers.cacheDisabled(getClass().getClassLoader())), new SimpleChannelUpstreamHandler() { @Override public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { if (e instanceof ChannelStateEvent && ((ChannelStateEvent) e).getState() != ChannelState.INTEREST_OPS) { LOG.info(e.toString()); } super.handleUpstream(ctx, e); } @Override public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent event) { channel = event.getChannel(); // Send the first message // channel.write(firstMessage); } @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) { // Get serverListener(e.getMessage()); ctx.sendUpstream(e); // e.getChannel().write(e.getStatus()); // e.getChannel().close(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { LOG.warn("Unexpected exception from downstream.", e.getCause()); e.getChannel().close(); } }); } }; // Set up the pipeline factory. this.clientBootstrap.setPipelineFactory(channelPipelineFactory); // Start the connection attempt. // ChannelFuture channelFuture = this.clientBootstrap.connect(new InetSocketAddress(host, // setPort)); LOG.debug("CLIENT GOING TO CONNECT - host:" + host + " post:" + port); this.channelFuture = this.clientBootstrap.connect(new InetSocketAddress(host, port)); // INFO // correct shut down a client // see http://netty.io/3.6/guide/#start.12 - 9. Shutting Down Your Application // http://stackoverflow.com/questions/10911988/shutting-down-netty-server-when-client-connections-are-open // Netty Server Shutdown // // Close server channel // Shutdown boss and worker executor // Release server bootstrap resource // Example code // // ChannelFuture cf = serverChannel.close(); // cf.awaitUninterruptibly(); // bossExecutor.shutdown(); // workerExecutor.shutdown(); // thriftServer.releaseExternalResources(); // TODO Need to repair it boolean goAway = false; long countGoAway = 0; final long stepGoAway = 50; // ms LOG.warn("Warming up 0.6.0-SNAPSHOT ..."); while (goAway == false | countGoAway < (SERVER_CONNECTION_TIMEOUT / stepGoAway)) { Thread.sleep(stepGoAway); if (!channelFuture.isSuccess()) { this.running = false; goAway = true; } else { this.running = true; goAway = true; countGoAway = (SERVER_CONNECTION_TIMEOUT / stepGoAway) + 10; } countGoAway++; LOG.warn( "Count down for connection tomeout:" + countGoAway * stepGoAway + ":ms future:" + channelFuture.isSuccess() + " running:" + this.running); } if (this.running == false) { LOG.warn("After "); channelFuture.getCause().printStackTrace(); channelFactory.releaseExternalResources(); channelFuture = null; } }
private void shutDownChannelFuture(ChannelFuture channelFutureLocal) { channelFutureLocal.getCause().printStackTrace(); channelFactory.releaseExternalResources(); channelFutureLocal = null; running = false; }
@Override protected void get(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // String uri = req.getParameter("uri"); String host = req.getParameter("host"); String appName = req.getParameter("app"); String streamName = req.getParameter("stream"); String scheme = req.getParameter("scheme"); String swfUri = req.getParameter("swfUri"); String pageUrl = req.getParameter("pageUrl"); logger.log(LogService.LOG_INFO, "StreamBridge params: " + req.getParameterMap()); resp.setContentType("video"); // add a filename int lastSlash = streamName.lastIndexOf('/'); String filename = lastSlash > 0 ? streamName.substring(lastSlash + 1) : streamName; resp.addHeader("Content-disposition", "attachment; filename=\"" + filename + ".flv\""); ClientOptions co; if ("rtmpe".equals(scheme)) { logger.log(LogService.LOG_INFO, "Trying to establish encrypted connection over rtmpe"); co = new ClientOptions(host, 1935, appName, streamName, "/tmp/dummy", true, null); } else { co = new ClientOptions(host, appName, streamName, "/tmp/dummy"); } if (swfUri != null) { try { RTMP.initSwfVerification(co, new URI(swfUri)); logger.log(LogService.LOG_INFO, "SWF verification initialized"); } catch (Exception e) { logger.log(LogService.LOG_ERROR, "Couldn't initialize SWF verification", e); } } if (pageUrl != null) { Map<String, Object> params = co.getParams(); if (params == null) { params = new HashMap<String, Object>(); co.setParams(params); } params.put("pageUrl", pageUrl); } OutputStreamFlvWriter writer = new OutputStreamFlvWriter( 0, resp.getOutputStream(), new DownloadListener() { @Override public void setProgress(int percent) {} @Override public void downloadFailed(Exception e) {} @Override public void downloadFinished() {} @Override public void downloadStarted() {} }); co.setWriterToSave(writer); logger.log( LogService.LOG_INFO, "Starting streaming: " + scheme + " " + host + " " + appName + " " + streamName); final ClientBootstrap bootstrap = RtmpDownload.getBootstrap(Executors.newCachedThreadPool(), new BandwidthMeterHandler(), co); final ChannelFuture future = bootstrap.connect(new InetSocketAddress(co.getHost(), co.getPort())); future.awaitUninterruptibly(); if (!future.isSuccess()) { logger.log(LogService.LOG_ERROR, "Error creating client connection", future.getCause()); throw new ServletException(new IOException("Error creating client connection")); } future.getChannel(); future.getChannel().getCloseFuture().awaitUninterruptibly(); bootstrap.getFactory().releaseExternalResources(); }
@Test public void testSslEcho() throws Throwable { ServerBootstrap sb = new ServerBootstrap(newServerSocketChannelFactory(Executors.newCachedThreadPool())); ClientBootstrap cb = new ClientBootstrap(newClientSocketChannelFactory(Executors.newCachedThreadPool())); EchoHandler sh = new EchoHandler(true); EchoHandler ch = new EchoHandler(false); SSLEngine sse = SecureChatSslContextFactory.getServerContext().createSSLEngine(); SSLEngine cse = SecureChatSslContextFactory.getClientContext().createSSLEngine(); sse.setUseClientMode(false); cse.setUseClientMode(true); // Workaround for blocking I/O transport write-write dead lock. sb.setOption("receiveBufferSize", 1048576); sb.setOption("receiveBufferSize", 1048576); sb.getPipeline().addFirst("ssl", new SslHandler(sse)); sb.getPipeline().addLast("handler", sh); cb.getPipeline().addFirst("ssl", new SslHandler(cse)); cb.getPipeline().addLast("handler", ch); ExecutorService eventExecutor = null; if (isExecutorRequired()) { eventExecutor = new OrderedMemoryAwareThreadPoolExecutor(16, 0, 0); sb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor)); cb.getPipeline().addFirst("executor", new ExecutionHandler(eventExecutor)); } Channel sc = sb.bind(new InetSocketAddress(0)); int port = ((InetSocketAddress) sc.getLocalAddress()).getPort(); ChannelFuture ccf = cb.connect(new InetSocketAddress(TestUtil.getLocalHost(), port)); ccf.awaitUninterruptibly(); if (!ccf.isSuccess()) { logger.error("Connection attempt failed", ccf.getCause()); sc.close().awaitUninterruptibly(); } assertTrue(ccf.isSuccess()); Channel cc = ccf.getChannel(); ChannelFuture hf = cc.getPipeline().get(SslHandler.class).handshake(); hf.awaitUninterruptibly(); if (!hf.isSuccess()) { logger.error("Handshake failed", hf.getCause()); sh.channel.close().awaitUninterruptibly(); ch.channel.close().awaitUninterruptibly(); sc.close().awaitUninterruptibly(); } assertTrue(hf.isSuccess()); for (int i = 0; i < data.length; ) { int length = Math.min(random.nextInt(1024 * 64), data.length - i); cc.write(ChannelBuffers.wrappedBuffer(data, i, length)); i += length; } while (ch.counter < data.length) { if (sh.exception.get() != null) { break; } if (ch.exception.get() != null) { break; } try { Thread.sleep(1); } catch (InterruptedException e) { // Ignore. } } while (sh.counter < data.length) { if (sh.exception.get() != null) { break; } if (ch.exception.get() != null) { break; } try { Thread.sleep(1); } catch (InterruptedException e) { // Ignore. } } sh.channel.close().awaitUninterruptibly(); ch.channel.close().awaitUninterruptibly(); sc.close().awaitUninterruptibly(); cb.shutdown(); sb.shutdown(); cb.releaseExternalResources(); sb.releaseExternalResources(); if (eventExecutor != null) { eventExecutor.shutdown(); } if (sh.exception.get() != null && !(sh.exception.get() instanceof IOException)) { throw sh.exception.get(); } if (ch.exception.get() != null && !(ch.exception.get() instanceof IOException)) { throw ch.exception.get(); } if (sh.exception.get() != null) { throw sh.exception.get(); } if (ch.exception.get() != null) { throw ch.exception.get(); } }