List of usage examples for io.netty.channel ChannelFuture isSuccess
boolean isSuccess();
From source file:com.relayrides.pushy.apns.ApnsClient.java
License:Open Source License
/** * <p>Connects to the given APNs gateway on the given port.</p> * * <p>Once an initial connection has been established and until the client has been explicitly disconnected via the * {@link ApnsClient#disconnect()} method, the client will attempt to reconnect automatically if the connection * closes unexpectedly. If the connection closes unexpectedly, callers may monitor the status of the reconnection * attempt with the {@code Future} returned by the {@link ApnsClient#getReconnectionFuture()} method.</p> * * @param host the APNs gateway to which to connect * @param port the port on which to connect to the APNs gateway * * @return a {@code Future} that will succeed when the client has connected to the gateway and is ready to send * push notifications//from w ww .jav a2 s . c o m * * @see ApnsClient#PRODUCTION_APNS_HOST * @see ApnsClient#DEVELOPMENT_APNS_HOST * @see ApnsClient#DEFAULT_APNS_PORT * @see ApnsClient#ALTERNATE_APNS_PORT * * @since 0.5 */ public Future<Void> connect(final String host, final int port) { final Future<Void> connectionReadyFuture; if (this.bootstrap.config().group().isShuttingDown() || this.bootstrap.config().group().isShutdown()) { connectionReadyFuture = new FailedFuture<>(GlobalEventExecutor.INSTANCE, new IllegalStateException( "Client's event loop group has been shut down and cannot be restarted.")); } else { synchronized (this.bootstrap) { // We only want to begin a connection attempt if one is not already in progress or complete; if we already // have a connection future, just return the existing promise. if (this.connectionReadyPromise == null) { this.metricsListener.handleConnectionAttemptStarted(this); final ChannelFuture connectFuture = this.bootstrap.connect(host, port); this.connectionReadyPromise = connectFuture.channel().newPromise(); connectFuture.addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture future) throws Exception { if (!future.isSuccess()) { final ChannelPromise connectionReadyPromise = ApnsClient.this.connectionReadyPromise; if (connectionReadyPromise != null) { // This may seem spurious, but our goal here is to accurately report the cause of // connection failure; if we just wait for connection closure, we won't be able to // tell callers anything more specific about what went wrong. connectionReadyPromise.tryFailure(future.cause()); } } } }); connectFuture.channel().closeFuture().addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture future) throws Exception { synchronized (ApnsClient.this.bootstrap) { if (ApnsClient.this.connectionReadyPromise != null) { // We always want to try to fail the "connection ready" promise if the connection // closes; if it has already succeeded, this will have no effect. ApnsClient.this.connectionReadyPromise.tryFailure(new IllegalStateException( "Channel closed before HTTP/2 preface completed.")); ApnsClient.this.connectionReadyPromise = null; } if (ApnsClient.this.reconnectionPromise != null) { log.debug("Disconnected. Next automatic reconnection attempt in {} seconds.", ApnsClient.this.reconnectDelaySeconds); ApnsClient.this.scheduledReconnectFuture = future.channel().eventLoop() .schedule(new Runnable() { @Override public void run() { log.debug("Attempting to reconnect."); ApnsClient.this.connect(host, port); } }, ApnsClient.this.reconnectDelaySeconds, TimeUnit.SECONDS); ApnsClient.this.reconnectDelaySeconds = Math.min( ApnsClient.this.reconnectDelaySeconds, MAX_RECONNECT_DELAY_SECONDS); } } } }); this.connectionReadyPromise.addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture future) throws Exception { if (future.isSuccess()) { synchronized (ApnsClient.this.bootstrap) { if (ApnsClient.this.reconnectionPromise != null) { log.info("Connection to {} restored.", future.channel().remoteAddress()); ApnsClient.this.reconnectionPromise.trySuccess(); } else { log.info("Connected to {}.", future.channel().remoteAddress()); } ApnsClient.this.reconnectDelaySeconds = INITIAL_RECONNECT_DELAY_SECONDS; ApnsClient.this.reconnectionPromise = future.channel().newPromise(); } ApnsClient.this.metricsListener.handleConnectionAttemptSucceeded(ApnsClient.this); } else { log.info("Failed to connect.", future.cause()); ApnsClient.this.metricsListener.handleConnectionAttemptFailed(ApnsClient.this); } } }); } connectionReadyFuture = this.connectionReadyPromise; } } return connectionReadyFuture; }
From source file:com.relayrides.pushy.apns.ApnsClient.java
License:Open Source License
/** * <p>Sends a push notification to the APNs gateway.</p> * * <p>This method returns a {@code Future} that indicates whether the notification was accepted or rejected by the * gateway. If the notification was accepted, it may be delivered to its destination device at some time in the * future, but final delivery is not guaranteed. Rejections should be considered permanent failures, and callers * should <em>not</em> attempt to re-send the notification.</p> * * <p>The returned {@code Future} may fail with an exception if the notification could not be sent. Failures to * <em>send</em> a notification to the gatewayi.e. those that fail with exceptionsshould generally be considered * non-permanent, and callers should attempt to re-send the notification when the underlying problem has been * resolved.</p>/*w w w . jav a 2 s.c o m*/ * * <p>In particular, attempts to send a notification when the client is not connected will fail with a * {@link ClientNotConnectedException}. If the client was previously connected and has not been explicitly * disconnected (via the {@link ApnsClient#disconnect()} method), the client will attempt to reconnect * automatically. Callers may wait for a reconnection attempt to complete by waiting for the {@code Future} returned * by the {@link ApnsClient#getReconnectionFuture()} method.</p> * * @param notification the notification to send to the APNs gateway * * @param <T> the type of notification to be sent * * @return a {@code Future} that will complete when the notification has been either accepted or rejected by the * APNs gateway * * @since 0.8 */ @SuppressWarnings({ "rawtypes", "unchecked" }) public <T extends ApnsPushNotification> Future<PushNotificationResponse<T>> sendNotification( final T notification) { final Future<PushNotificationResponse<T>> responseFuture; final long notificationId = this.nextNotificationId.getAndIncrement(); // Instead of synchronizing here, we keep a final reference to the connection ready promise. We can get away // with this because we're not changing the state of the connection or its promises. Keeping a reference ensures // we won't suddenly "lose" the channel and get a NullPointerException, but risks sending a notification after // things have shut down. In that case, though, the returned futures should fail quickly, and the benefit of // not synchronizing for every write seems worth it. final ChannelPromise connectionReadyPromise = this.connectionReadyPromise; if (connectionReadyPromise != null && connectionReadyPromise.isSuccess() && connectionReadyPromise.channel().isActive()) { final Channel channel = connectionReadyPromise.channel(); final Promise<PushNotificationResponse<ApnsPushNotification>> responsePromise = new DefaultPromise( channel.eventLoop()); channel.writeAndFlush(new PushNotificationAndResponsePromise(notification, responsePromise)) .addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture future) throws Exception { if (future.isSuccess()) { ApnsClient.this.metricsListener.handleNotificationSent(ApnsClient.this, notificationId); } else { responsePromise.tryFailure(future.cause()); } } }); responseFuture = (Future) responsePromise; } else { log.debug("Failed to send push notification because client is not connected: {}", notification); responseFuture = new FailedFuture<>(GlobalEventExecutor.INSTANCE, NOT_CONNECTED_EXCEPTION); } responseFuture.addListener(new GenericFutureListener<Future<PushNotificationResponse<T>>>() { @Override public void operationComplete(final Future<PushNotificationResponse<T>> future) throws Exception { if (future.isSuccess()) { final PushNotificationResponse<T> response = future.getNow(); if (response.isAccepted()) { ApnsClient.this.metricsListener.handleNotificationAccepted(ApnsClient.this, notificationId); } else { ApnsClient.this.metricsListener.handleNotificationRejected(ApnsClient.this, notificationId); } } else { ApnsClient.this.metricsListener.handleWriteFailure(ApnsClient.this, notificationId); } } }); return responseFuture; }
From source file:com.relayrides.pushy.apns.ApnsClientHandler.java
License:Open Source License
@Override public void userEventTriggered(final ChannelHandlerContext context, final Object event) throws Exception { if (event instanceof IdleStateEvent) { assert PING_TIMEOUT < ApnsClient.PING_IDLE_TIME_MILLIS; log.trace("Sending ping due to inactivity."); final ByteBuf pingDataBuffer = context.alloc().ioBuffer(8, 8); pingDataBuffer.writeLong(this.nextPingId++); this.encoder().writePing(context, false, pingDataBuffer, context.newPromise()) .addListener(new GenericFutureListener<ChannelFuture>() { @Override/*w w w. ja v a 2s.c o m*/ public void operationComplete(final ChannelFuture future) throws Exception { if (future.isSuccess()) { ApnsClientHandler.this.pingTimeoutFuture = future.channel().eventLoop() .schedule(new Runnable() { @Override public void run() { log.debug("Closing channel due to ping timeout."); future.channel().close(); } }, PING_TIMEOUT, TimeUnit.SECONDS); } else { log.debug("Failed to write PING frame.", future.cause()); future.channel().close(); } } }); this.flush(context); } super.userEventTriggered(context, event); }
From source file:com.relayrides.pushy.apns.ApnsConnection.java
License:Open Source License
/** * Asynchronously connects to the APNs gateway in this connection's environment. The outcome of the connection * attempt is reported via this connection's listener. * * @see ApnsConnectionListener#handleConnectionSuccess(ApnsConnection) * @see ApnsConnectionListener#handleConnectionFailure(ApnsConnection, Throwable) */// w ww . j a v a 2 s .c o m @SuppressWarnings("deprecation") public synchronized void connect() { final ApnsConnection<T> apnsConnection = this; if (this.connectFuture != null) { throw new IllegalStateException(String.format("%s already started a connection attempt.", this.name)); } final Bootstrap bootstrap = new Bootstrap(); bootstrap.group(this.eventLoopGroup); bootstrap.channel(NioSocketChannel.class); bootstrap.option(ChannelOption.SO_KEEPALIVE, true); bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); // TODO Remove this when Netty 5 is available bootstrap.option(ChannelOption.AUTO_CLOSE, false); bootstrap.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(final SocketChannel channel) { final ChannelPipeline pipeline = channel.pipeline(); final SSLEngine sslEngine = apnsConnection.sslContext.createSSLEngine(); sslEngine.setUseClientMode(true); pipeline.addLast("ssl", new SslHandler(sslEngine)); pipeline.addLast("decoder", new RejectedNotificationDecoder()); pipeline.addLast("encoder", new ApnsPushNotificationEncoder()); pipeline.addLast("handler", new ApnsConnectionHandler(apnsConnection)); } }); log.debug("{} beginning connection process.", apnsConnection.name); this.connectFuture = bootstrap.connect(this.environment.getApnsGatewayHost(), this.environment.getApnsGatewayPort()); this.connectFuture.addListener(new GenericFutureListener<ChannelFuture>() { public void operationComplete(final ChannelFuture connectFuture) { if (connectFuture.isSuccess()) { log.debug("{} connected; waiting for TLS handshake.", apnsConnection.name); final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class); try { sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() { public void operationComplete(final Future<Channel> handshakeFuture) { if (handshakeFuture.isSuccess()) { log.debug("{} successfully completed TLS handshake.", apnsConnection.name); apnsConnection.handshakeCompleted = true; apnsConnection.listener.handleConnectionSuccess(apnsConnection); } else { log.debug("{} failed to complete TLS handshake with APNs gateway.", apnsConnection.name, handshakeFuture.cause()); connectFuture.channel().close(); apnsConnection.listener.handleConnectionFailure(apnsConnection, handshakeFuture.cause()); } } }); } catch (NullPointerException e) { log.warn("{} failed to get SSL handler and could not wait for a TLS handshake.", apnsConnection.name); connectFuture.channel().close(); apnsConnection.listener.handleConnectionFailure(apnsConnection, e); } } else { log.debug("{} failed to connect to APNs gateway.", apnsConnection.name, connectFuture.cause()); apnsConnection.listener.handleConnectionFailure(apnsConnection, connectFuture.cause()); } } }); }
From source file:com.relayrides.pushy.apns.ApnsConnection.java
License:Open Source License
/** * Asynchronously sends a push notification to the connected APNs gateway. Successful notifications are * <strong>not</strong> acknowledged by the APNs gateway; failed attempts to write push notifications to the * outbound buffer and notification rejections are reported via this connection's listener. * * @param notification the notification to send * * @see ApnsConnectionListener#handleWriteFailure(ApnsConnection, ApnsPushNotification, Throwable) * @see ApnsConnectionListener#handleRejectedNotification(ApnsConnection, ApnsPushNotification, RejectedNotificationReason) *//*from www.j a v a 2s. c om*/ public synchronized void sendNotification(final T notification) { final ApnsConnection<T> apnsConnection = this; if (!this.handshakeCompleted) { throw new IllegalStateException(String.format("%s has not completed handshake.", this.name)); } this.connectFuture.channel().eventLoop().execute(new Runnable() { public void run() { final SendableApnsPushNotification<T> sendableNotification = new SendableApnsPushNotification<T>( notification, apnsConnection.sequenceNumber++); log.trace("{} sending {}", apnsConnection.name, sendableNotification); apnsConnection.pendingWriteCount += 1; apnsConnection.connectFuture.channel().writeAndFlush(sendableNotification) .addListener(new GenericFutureListener<ChannelFuture>() { public void operationComplete(final ChannelFuture writeFuture) { if (writeFuture.isSuccess()) { log.trace("{} successfully wrote notification {}", apnsConnection.name, sendableNotification.getSequenceNumber()); if (apnsConnection.rejectionReceived) { // Even though the write succeeded, we know for sure that this notification was never // processed by the gateway because it had already rejected another notification from // this connection. apnsConnection.listener.handleUnprocessedNotifications(apnsConnection, java.util.Collections.singletonList(notification)); } else { apnsConnection.sentNotificationBuffer .addSentNotification(sendableNotification); } } else { log.trace("{} failed to write notification {}", apnsConnection.name, sendableNotification, writeFuture.cause()); // Assume this is a temporary failure (we know it's not a permanent rejection because we didn't // even manage to write the notification to the wire) and re-enqueue for another send attempt. apnsConnection.listener.handleWriteFailure(apnsConnection, notification, writeFuture.cause()); } apnsConnection.pendingWriteCount -= 1; assert apnsConnection.pendingWriteCount >= 0; if (apnsConnection.pendingWriteCount == 0) { synchronized (apnsConnection.pendingWriteMonitor) { apnsConnection.pendingWriteMonitor.notifyAll(); } } } }); } }); }
From source file:com.relayrides.pushy.apns.ApnsConnection.java
License:Open Source License
/** * <p>Gracefully and asynchronously shuts down this connection. Graceful disconnection is triggered by sending a * known-bad notification to the APNs gateway; when the gateway rejects the notification, it is guaranteed that * preceding notifications were processed successfully and that all following notifications were not processed at * all. The gateway will close the connection after rejecting the notification, and this connection's listener will * be notified when the connection is closed.</p> * * <p>Note that if/when the known-bad notification is rejected by the APNs gateway, this connection's listener will * <em>not</em> be notified of the rejection.</p> * * <p>Calling this method before establishing a connection with the APNs gateway or while a graceful shutdown * attempt is already in progress has no effect.</p> * * @see ApnsConnectionListener#handleRejectedNotification(ApnsConnection, ApnsPushNotification, RejectedNotificationReason) * @see ApnsConnectionListener#handleConnectionClosure(ApnsConnection) *//*from ww w. jav a2 s .c o m*/ public synchronized void shutdownGracefully() { final ApnsConnection<T> apnsConnection = this; // We only need to send a known-bad notification if we were ever connected in the first place and if we're // still connected. if (this.handshakeCompleted && this.connectFuture.channel().isActive()) { this.connectFuture.channel().eventLoop().execute(new Runnable() { public void run() { // Don't send a second shutdown notification if we've already started the graceful shutdown process. if (apnsConnection.shutdownNotification == null) { log.debug("{} sending known-bad notification to shut down.", apnsConnection.name); apnsConnection.shutdownNotification = new SendableApnsPushNotification<KnownBadPushNotification>( new KnownBadPushNotification(), apnsConnection.sequenceNumber++); apnsConnection.pendingWriteCount += 1; apnsConnection.connectFuture.channel().writeAndFlush(apnsConnection.shutdownNotification) .addListener(new GenericFutureListener<ChannelFuture>() { public void operationComplete(final ChannelFuture future) { if (future.isSuccess()) { log.trace("{} successfully wrote known-bad notification {}", apnsConnection.name, apnsConnection.shutdownNotification.getSequenceNumber()); } else { log.trace("{} failed to write known-bad notification {}", apnsConnection.name, apnsConnection.shutdownNotification, future.cause()); // Try again! apnsConnection.shutdownNotification = null; apnsConnection.shutdownGracefully(); } apnsConnection.pendingWriteCount -= 1; assert apnsConnection.pendingWriteCount >= 0; if (apnsConnection.pendingWriteCount == 0) { synchronized (apnsConnection.pendingWriteMonitor) { apnsConnection.pendingWriteMonitor.notifyAll(); } } } }); } } }); } else { // While we can't guarantee that the handshake won't complete in another thread, we CAN guarantee that no // new notifications will be sent until shutdownImmediately happens because everything is synchronized. this.shutdownImmediately(); } }
From source file:com.relayrides.pushy.apns.FeedbackServiceClient.java
License:Open Source License
/** * <p>Retrieves a list of expired tokens from the APNs feedback service. Be warned that this is a * <strong>destructive operation</strong>. According to Apple's documentation:</p> * * <blockquote>The feedback service's list is cleared after you read it. Each time you connect to the feedback * service, the information it returns lists only the failures that have happened since you last * connected.</blockquote>/*from w w w . j a v a 2s . c o m*/ * * @param timeout the time after the last received data after which the connection to the feedback service should * be closed * @param timeoutUnit the unit of time in which the given {@code timeout} is measured * * @return a list of tokens that have expired since the last connection to the feedback service * * @throws InterruptedException if interrupted while waiting for a response from the feedback service * @throws FeedbackConnectionException if the connection to the feedback service failed for any reason */ public synchronized List<ExpiredToken> getExpiredTokens(final long timeout, final TimeUnit timeoutUnit) throws InterruptedException, FeedbackConnectionException { this.expiredTokens.clear(); final Bootstrap bootstrap = new Bootstrap(); bootstrap.group(this.eventLoopGroup); bootstrap.channel(NioSocketChannel.class); final FeedbackServiceClient feedbackClient = this; bootstrap.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(final SocketChannel channel) throws Exception { final ChannelPipeline pipeline = channel.pipeline(); final SSLEngine sslEngine = feedbackClient.sslContext.createSSLEngine(); sslEngine.setUseClientMode(true); pipeline.addLast("ssl", new SslHandler(sslEngine)); pipeline.addLast("readTimeoutHandler", new ReadTimeoutHandler(timeout, timeoutUnit)); pipeline.addLast("decoder", new ExpiredTokenDecoder()); pipeline.addLast("handler", new FeedbackClientHandler(feedbackClient)); } }); final ChannelFuture connectFuture = bootstrap .connect(this.environment.getFeedbackHost(), this.environment.getFeedbackPort()).await(); if (connectFuture.isSuccess()) { log.debug("Connected to feedback service."); final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class); if (sslHandler != null) { final Future<Channel> handshakeFuture = sslHandler.handshakeFuture().await(); if (handshakeFuture.isSuccess()) { log.debug("Completed TLS handshake with feedback service."); // The feedback service will send us a list of device tokens as soon as we complete the SSL // handshake, then hang up. While we're waiting to sync with the connection closure, we'll be // receiving messages from the feedback service from another thread. connectFuture.channel().closeFuture().await(); } else { log.debug("Failed to complete TLS handshake with feedback service.", handshakeFuture.cause()); connectFuture.channel().close().await(); throw new FeedbackConnectionException(handshakeFuture.cause()); } } else { log.warn("Feedback client failed to get SSL handler and could not wait for TLS handshake."); connectFuture.channel().close().await(); throw new FeedbackConnectionException(null); } } else { log.debug("Failed to connect to feedback service.", connectFuture.cause()); throw new FeedbackConnectionException(connectFuture.cause()); } return new ArrayList<ExpiredToken>(this.expiredTokens); }
From source file:com.relayrides.pushy.apns.FeedbackServiceConnection.java
License:Open Source License
/** * <p>Connects to the APNs feedback service and waits for expired tokens to arrive. Be warned that this is a * <strong>destructive operation</strong>. According to Apple's documentation:</p> * * <blockquote>The feedback service's list is cleared after you read it. Each time you connect to the feedback * service, the information it returns lists only the failures that have happened since you last * connected.</blockquote>/*from w w w . j a v a2 s. c o m*/ */ public synchronized void connect() { if (this.connectFuture != null) { throw new IllegalStateException(String.format("%s already started a connection attempt.", this.name)); } final Bootstrap bootstrap = new Bootstrap(); bootstrap.group(this.eventLoopGroup); bootstrap.channel(NioSocketChannel.class); final FeedbackServiceConnection feedbackConnection = this; bootstrap.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(final SocketChannel channel) throws Exception { final ChannelPipeline pipeline = channel.pipeline(); final SSLEngine sslEngine = feedbackConnection.sslContext.createSSLEngine(); sslEngine.setUseClientMode(true); pipeline.addLast("ssl", new SslHandler(sslEngine)); pipeline.addLast("readTimeoutHandler", new ReadTimeoutHandler(feedbackConnection.configuration.getReadTimeout())); pipeline.addLast("decoder", new ExpiredTokenDecoder()); pipeline.addLast("handler", new FeedbackClientHandler(feedbackConnection)); } }); this.connectFuture = bootstrap.connect(this.environment.getFeedbackHost(), this.environment.getFeedbackPort()); this.connectFuture.addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(final ChannelFuture connectFuture) { if (connectFuture.isSuccess()) { log.debug("{} connected; waiting for TLS handshake.", feedbackConnection.name); final SslHandler sslHandler = connectFuture.channel().pipeline().get(SslHandler.class); try { sslHandler.handshakeFuture().addListener(new GenericFutureListener<Future<Channel>>() { @Override public void operationComplete(final Future<Channel> handshakeFuture) { if (handshakeFuture.isSuccess()) { log.debug("{} successfully completed TLS handshake.", feedbackConnection.name); if (feedbackConnection.listener != null) { feedbackConnection.listener.handleConnectionSuccess(feedbackConnection); } } else { log.debug("{} failed to complete TLS handshake with APNs feedback service.", feedbackConnection.name, handshakeFuture.cause()); connectFuture.channel().close(); if (feedbackConnection.listener != null) { feedbackConnection.listener.handleConnectionFailure(feedbackConnection, handshakeFuture.cause()); } } } }); } catch (NullPointerException e) { log.warn("{} failed to get SSL handler and could not wait for a TLS handshake.", feedbackConnection.name); connectFuture.channel().close(); if (feedbackConnection.listener != null) { feedbackConnection.listener.handleConnectionFailure(feedbackConnection, e); } } } else { log.debug("{} failed to connect to APNs feedback service.", feedbackConnection.name, connectFuture.cause()); if (feedbackConnection.listener != null) { feedbackConnection.listener.handleConnectionFailure(feedbackConnection, connectFuture.cause()); } } } }); }
From source file:com.repo.netty.proxy.HexDumpProxyFrontendHandler.java
License:Apache License
@Override public void channelActive(ChannelHandlerContext ctx) { final Channel inboundChannel = ctx.channel(); // Start the connection attempt. Bootstrap b = new Bootstrap(); b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass()) .handler(new HexDumpProxyBackendHandler(inboundChannel)).option(ChannelOption.AUTO_READ, false); ChannelFuture f = b.connect(remoteHost, remotePort); outboundChannel = f.channel();//from w w w .j a va 2 s . co m f.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) { if (future.isSuccess()) { // connection complete start to read first data inboundChannel.read(); } else { // Close the connection if the connection attempt has failed. inboundChannel.close(); } } }); }
From source file:com.sangupta.swift.netty.proxy.ProxyBackendHandler.java
License:Apache License
@Override public void channelRead(final ChannelHandlerContext channelHandlerContext, Object message) { inboundChannel.writeAndFlush(message).addListener(new ChannelFutureListener() { @Override/*from ww w . j a va2 s. c o m*/ public void operationComplete(ChannelFuture future) { if (future.isSuccess()) { channelHandlerContext.channel().read(); } else { future.channel().close(); } } }); }