Example usage for io.netty.channel ChannelFutureListener ChannelFutureListener

List of usage examples for io.netty.channel ChannelFutureListener ChannelFutureListener

Introduction

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

Prototype

ChannelFutureListener

Source Link

Usage

From source file:io.grpc.netty.NettyClientHandler.java

License:Apache License

private void createStreamTraced(final int streamId, final NettyClientStream.TransportState stream,
        final Http2Headers headers, boolean isGet, final boolean shouldBeCountedForInUse,
        final ChannelPromise promise) {
    // Create an intermediate promise so that we can intercept the failure reported back to the
    // application.
    ChannelPromise tempPromise = ctx().newPromise();
    encoder().writeHeaders(ctx(), streamId, headers, 0, isGet, tempPromise)
            .addListener(new ChannelFutureListener() {
                @Override//from   w w  w .  ja  v a 2  s  .  c  o  m
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (future.isSuccess()) {
                        // The http2Stream will be null in case a stream buffered in the encoder
                        // was canceled via RST_STREAM.
                        Http2Stream http2Stream = connection().stream(streamId);
                        if (http2Stream != null) {
                            stream.getStatsTraceContext().clientOutboundHeaders();
                            http2Stream.setProperty(streamKey, stream);

                            // This delays the in-use state until the I/O completes, which technically may
                            // be later than we would like.
                            if (shouldBeCountedForInUse) {
                                inUseState.updateObjectInUse(http2Stream, true);
                            }

                            // Attach the client stream to the HTTP/2 stream object as user data.
                            stream.setHttp2Stream(http2Stream);
                        }
                        // Otherwise, the stream has been cancelled and Netty is sending a
                        // RST_STREAM frame which causes it to purge pending writes from the
                        // flow-controller and delete the http2Stream. The stream listener has already
                        // been notified of cancellation so there is nothing to do.

                        // Just forward on the success status to the original promise.
                        promise.setSuccess();
                    } else {
                        final Throwable cause = future.cause();
                        if (cause instanceof StreamBufferingEncoder.Http2GoAwayException) {
                            StreamBufferingEncoder.Http2GoAwayException e = (StreamBufferingEncoder.Http2GoAwayException) cause;
                            lifecycleManager.notifyShutdown(statusFromGoAway(e.errorCode(), e.debugData()));
                            promise.setFailure(lifecycleManager.getShutdownThrowable());
                        } else {
                            promise.setFailure(cause);
                        }
                    }
                }
            });
}

From source file:io.grpc.netty.NettyClientHandler.java

License:Apache License

/**
 * Sends a PING frame. If a ping operation is already outstanding, the callback in the message is
 * registered to be called when the existing operation completes, and no new frame is sent.
 *//*ww w  .j ava  2 s.co m*/
private void sendPingFrameTraced(ChannelHandlerContext ctx, SendPingCommand msg, ChannelPromise promise) {
    // Don't check lifecycleManager.getShutdownStatus() since we want to allow pings after shutdown
    // but before termination. After termination, messages will no longer arrive because the
    // pipeline clears all handlers on channel close.

    PingCallback callback = msg.callback();
    Executor executor = msg.executor();
    // we only allow one outstanding ping at a time, so just add the callback to
    // any outstanding operation
    if (ping != null) {
        promise.setSuccess();
        ping.addCallback(callback, executor);
        return;
    }

    // Use a new promise to prevent calling the callback twice on write failure: here and in
    // NettyClientTransport.ping(). It may appear strange, but it will behave the same as if
    // ping != null above.
    promise.setSuccess();
    promise = ctx().newPromise();
    // set outstanding operation
    long data = USER_PING_PAYLOAD;
    Stopwatch stopwatch = stopwatchFactory.get();
    stopwatch.start();
    ping = new Http2Ping(data, stopwatch);
    ping.addCallback(callback, executor);
    // and then write the ping
    encoder().writePing(ctx, false, USER_PING_PAYLOAD, promise);
    ctx.flush();
    final Http2Ping finalPing = ping;
    promise.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (future.isSuccess()) {
                transportTracer.reportKeepAliveSent();
            } else {
                Throwable cause = future.cause();
                if (cause instanceof ClosedChannelException) {
                    cause = lifecycleManager.getShutdownThrowable();
                    if (cause == null) {
                        cause = Status.UNKNOWN.withDescription("Ping failed but for unknown reason.")
                                .withCause(future.cause()).asException();
                    }
                }
                finalPing.failed(cause);
                if (ping == finalPing) {
                    ping = null;
                }
            }
        }
    });
}

From source file:io.grpc.netty.NettyClientTransport.java

License:Apache License

@Override
public void ping(final PingCallback callback, final Executor executor) {
    if (channel == null) {
        executor.execute(new Runnable() {
            @Override//w  ww  .  j a v a2  s  . c om
            public void run() {
                callback.onFailure(statusExplainingWhyTheChannelIsNull.asException());
            }
        });
        return;
    }
    // The promise and listener always succeed in NettyClientHandler. So this listener handles the
    // error case, when the channel is closed and the NettyClientHandler no longer in the pipeline.
    ChannelFutureListener failureListener = new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                Status s = statusFromFailedFuture(future);
                Http2Ping.notifyFailed(callback, executor, s.asException());
            }
        }
    };
    // Write the command requesting the ping
    handler.getWriteQueue().enqueue(new SendPingCommand(callback, executor), true).addListener(failureListener);
}

From source file:io.grpc.netty.NettyClientTransport.java

License:Apache License

@SuppressWarnings("unchecked")
@Override/* w w w  .j a  v  a  2  s  .c  o m*/
public Runnable start(Listener transportListener) {
    lifecycleManager = new ClientTransportLifecycleManager(
            Preconditions.checkNotNull(transportListener, "listener"));
    EventLoop eventLoop = group.next();
    if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED) {
        keepAliveManager = new KeepAliveManager(new ClientKeepAlivePinger(this), eventLoop, keepAliveTimeNanos,
                keepAliveTimeoutNanos, keepAliveWithoutCalls);
    }

    handler = NettyClientHandler.newHandler(lifecycleManager, keepAliveManager, flowControlWindow,
            maxHeaderListSize, GrpcUtil.STOPWATCH_SUPPLIER, tooManyPingsRunnable, transportTracer,
            eagAttributes, authorityString);
    NettyHandlerSettings.setAutoWindow(handler);

    ChannelHandler negotiationHandler = negotiator.newHandler(handler);

    Bootstrap b = new Bootstrap();
    b.attr(LOGGER_KEY, channelLogger);
    b.group(eventLoop);
    b.channelFactory(channelFactory);
    // For non-socket based channel, the option will be ignored.
    b.option(SO_KEEPALIVE, true);
    // For non-epoll based channel, the option will be ignored.
    if (keepAliveTimeNanos != KEEPALIVE_TIME_NANOS_DISABLED) {
        ChannelOption<Integer> tcpUserTimeout = Utils.maybeGetTcpUserTimeoutOption();
        if (tcpUserTimeout != null) {
            b.option(tcpUserTimeout, (int) TimeUnit.NANOSECONDS.toMillis(keepAliveTimeoutNanos));
        }
    }
    for (Map.Entry<ChannelOption<?>, ?> entry : channelOptions.entrySet()) {
        // Every entry in the map is obtained from
        // NettyChannelBuilder#withOption(ChannelOption<T> option, T value)
        // so it is safe to pass the key-value pair to b.option().
        b.option((ChannelOption<Object>) entry.getKey(), entry.getValue());
    }

    ChannelHandler bufferingHandler = new WriteBufferingAndExceptionHandler(negotiationHandler);

    /**
     * We don't use a ChannelInitializer in the client bootstrap because its "initChannel" method
     * is executed in the event loop and we need this handler to be in the pipeline immediately so
     * that it may begin buffering writes.
     */
    b.handler(bufferingHandler);
    ChannelFuture regFuture = b.register();
    if (regFuture.isDone() && !regFuture.isSuccess()) {
        channel = null;
        // Initialization has failed badly. All new streams should be made to fail.
        Throwable t = regFuture.cause();
        if (t == null) {
            t = new IllegalStateException("Channel is null, but future doesn't have a cause");
        }
        statusExplainingWhyTheChannelIsNull = Utils.statusFromThrowable(t);
        // Use a Runnable since lifecycleManager calls transportListener
        return new Runnable() {
            @Override
            public void run() {
                // NOTICE: we not are calling lifecycleManager from the event loop. But there isn't really
                // an event loop in this case, so nothing should be accessing the lifecycleManager. We
                // could use GlobalEventExecutor (which is what regFuture would use for notifying
                // listeners in this case), but avoiding on-demand thread creation in an error case seems
                // a good idea and is probably clearer threading.
                lifecycleManager.notifyTerminated(statusExplainingWhyTheChannelIsNull);
            }
        };
    }
    channel = regFuture.channel();
    // Start the write queue as soon as the channel is constructed
    handler.startWriteQueue(channel);
    // This write will have no effect, yet it will only complete once the negotiationHandler
    // flushes any pending writes. We need it to be staged *before* the `connect` so that
    // the channel can't have been closed yet, removing all handlers. This write will sit in the
    // AbstractBufferingHandler's buffer, and will either be flushed on a successful connection,
    // or failed if the connection fails.
    channel.writeAndFlush(NettyClientHandler.NOOP_MESSAGE).addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                // Need to notify of this failure, because NettyClientHandler may not have been added to
                // the pipeline before the error occurred.
                lifecycleManager.notifyTerminated(Utils.statusFromThrowable(future.cause()));
            }
        }
    });
    // Start the connection operation to the server.
    SocketAddress localAddress = localSocketPicker.createSocketAddress(remoteAddress, eagAttributes);
    if (localAddress != null) {
        channel.connect(remoteAddress, localAddress);
    } else {
        channel.connect(remoteAddress);
    }

    if (keepAliveManager != null) {
        keepAliveManager.onTransportStarted();
    }

    return null;
}

From source file:io.grpc.netty.NettyServer.java

License:Apache License

@Override
public void shutdown() {
    if (channel == null || !channel.isOpen()) {
        // Already closed.
        return;/*w ww.j  ava 2s  . com*/
    }
    channel.close().addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            if (!future.isSuccess()) {
                log.log(Level.WARNING, "Error shutting down server", future.cause());
            }
            InternalInstrumented<SocketStats> stats = listenSocketStats.getAndSet(null);
            if (stats != null) {
                channelz.removeListenSocket(stats);
            }
            synchronized (NettyServer.this) {
                listener.serverShutdown();
            }
            eventLoopReferenceCounter.release();
        }
    });
    try {
        channel.closeFuture().await();
    } catch (InterruptedException e) {
        log.log(Level.FINE, "Interrupted while shutting down", e);
        Thread.currentThread().interrupt();
    }
}

From source file:io.grpc.netty.NettyServerHandler.java

License:Apache License

private void closeStreamWhenDone(ChannelPromise promise, int streamId) throws Http2Exception {
    final NettyServerStream.TransportState stream = serverStream(requireHttp2Stream(streamId));
    promise.addListener(new ChannelFutureListener() {
        @Override//from   ww w.ja  va  2  s .c om
        public void operationComplete(ChannelFuture future) {
            stream.complete();
        }
    });
}

From source file:io.hydramq.network.client.AbstractConnection.java

License:Open Source License

@Override
public CompletableFuture<Void> disconnect() {
    CompletableFuture<Void> future = new CompletableFuture<>();
    channel().close().addListener(new ChannelFutureListener() {
        @Override//from  ww w .  ja v a2  s . c o  m
        public void operationComplete(final ChannelFuture closeFuture) throws Exception {
            if (closeFuture.isSuccess()) {
                future.complete(null);
                logger.info("Disconnected");
            } else {
                future.completeExceptionally(closeFuture.cause());
            }
        }
    });
    return future;
}

From source file:io.jsync.http.impl.ClientConnection.java

License:Open Source License

void toWebSocket(String uri, final WebSocketVersion wsVersion, final MultiMap headers,
        int maxWebSocketFrameSize, final Set<String> subProtocols, final Handler<WebSocket> wsConnect) {
    if (ws != null) {
        throw new IllegalStateException("Already websocket");
    }//w  ww . ja  v a  2  s.  c o  m

    try {
        URI wsuri = new URI(uri);
        if (!wsuri.isAbsolute()) {
            // Netty requires an absolute url
            wsuri = new URI((ssl ? "https:" : "http:") + "//" + host + ":" + port + uri);
        }
        io.netty.handler.codec.http.websocketx.WebSocketVersion version;
        if (wsVersion == WebSocketVersion.HYBI_00) {
            version = io.netty.handler.codec.http.websocketx.WebSocketVersion.V00;
        } else if (wsVersion == WebSocketVersion.HYBI_08) {
            version = io.netty.handler.codec.http.websocketx.WebSocketVersion.V08;
        } else if (wsVersion == WebSocketVersion.RFC6455) {
            version = io.netty.handler.codec.http.websocketx.WebSocketVersion.V13;
        } else {
            throw new IllegalArgumentException("Invalid version");
        }
        HttpHeaders nettyHeaders;
        if (headers != null) {
            nettyHeaders = new DefaultHttpHeaders();
            for (Map.Entry<String, String> entry : headers) {
                nettyHeaders.add(entry.getKey(), entry.getValue());
            }
        } else {
            nettyHeaders = null;
        }
        String wsSubProtocols = null;
        if (subProtocols != null && !subProtocols.isEmpty()) {
            StringBuilder sb = new StringBuilder();

            Iterator<String> protocols = subProtocols.iterator();
            while (protocols.hasNext()) {
                sb.append(protocols.next());
                if (protocols.hasNext()) {
                    sb.append(",");
                }
            }
            wsSubProtocols = sb.toString();
        }
        handshaker = WebSocketClientHandshakerFactory.newHandshaker(wsuri, version, wsSubProtocols, false,
                nettyHeaders, maxWebSocketFrameSize);
        final ChannelPipeline p = channel.pipeline();
        p.addBefore("handler", "handshakeCompleter", new HandshakeInboundHandler(wsConnect));
        handshaker.handshake(channel).addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (!future.isSuccess()) {
                    client.handleException((Exception) future.cause());
                }
            }
        });
        upgradedConnection = true;

    } catch (Exception e) {
        handleException(e);
    }
}

From source file:io.jsync.http.impl.DefaultHttpClient.java

License:Open Source License

void internalConnect(final Handler<ClientConnection> connectHandler,
        final Handler<Throwable> connectErrorHandler) {
    if (bootstrap == null) {
        // Share the event loop thread to also serve the HttpClient's network traffic.
        AsyncEventLoopGroup pool = new AsyncEventLoopGroup();
        pool.addWorker(actualCtx.getEventLoop());
        bootstrap = new Bootstrap();
        bootstrap.group(pool);//from  www  . j  a v  a 2  s.  co m
        bootstrap.channel(NioSocketChannel.class);
        tcpHelper.checkSSL(async);

        bootstrap.handler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                if (tcpHelper.isSSL()) {
                    pipeline.addLast("ssl", tcpHelper.createSslHandler(async, true, host, port));
                }
                pipeline.addLast("codec", new HttpClientCodec(4096, 8192, 8192, false, false));
                if (tryUseCompression) {
                    pipeline.addLast("inflater", new HttpContentDecompressor(true));
                }
                pipeline.addLast("handler", new ClientHandler());
            }
        });
    }
    tcpHelper.applyConnectionOptions(bootstrap);
    ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
    future.addListener(new ChannelFutureListener() {
        public void operationComplete(ChannelFuture channelFuture) throws Exception {
            final Channel ch = channelFuture.channel();
            if (channelFuture.isSuccess()) {
                if (tcpHelper.isSSL()) {
                    // TCP connected, so now we must do the SSL handshake

                    SslHandler sslHandler = ch.pipeline().get(SslHandler.class);

                    Future<Channel> fut = sslHandler.handshakeFuture();
                    fut.addListener(new GenericFutureListener<Future<Channel>>() {
                        @Override
                        public void operationComplete(Future<Channel> future) throws Exception {
                            if (future.isSuccess()) {
                                connected(ch, connectHandler);
                            } else {
                                connectionFailed(ch, connectErrorHandler,
                                        new SSLHandshakeException("Failed to create SSL connection"));
                            }
                        }
                    });
                } else {
                    connected(ch, connectHandler);
                }
            } else {
                connectionFailed(ch, connectErrorHandler, channelFuture.cause());
            }
        }
    });
}

From source file:io.jsync.http.impl.DefaultHttpServer.java

License:Open Source License

public HttpServer listen(int port, String host, final Handler<AsyncResult<HttpServer>> listenHandler) {
    if (requestHandler == null && wsHandler == null) {
        throw new IllegalStateException("Set request or websocket handler first");
    }// w  w  w  .j  ava  2  s . c  o  m
    if (listening) {
        throw new IllegalStateException("Listen already called");
    }
    listening = true;

    synchronized (async.sharedHttpServers()) {
        id = new ServerID(port, host);

        serverOrigin = (isSSL() ? "https" : "http") + "://" + host + ":" + port;

        DefaultHttpServer shared = async.sharedHttpServers().get(id);
        if (shared == null || port == 0) {
            serverChannelGroup = new DefaultChannelGroup("async-acceptor-channels",
                    GlobalEventExecutor.INSTANCE);
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(availableWorkers);
            bootstrap.channel(NioServerSocketChannel.class);
            tcpHelper.applyConnectionOptions(bootstrap);
            tcpHelper.checkSSL(async);
            bootstrap.childHandler(new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel ch) throws Exception {
                    ChannelPipeline pipeline = ch.pipeline();
                    if (tcpHelper.isSSL()) {
                        pipeline.addLast("ssl", tcpHelper.createSslHandler(async, false));
                    }
                    pipeline.addLast("flashpolicy", new FlashPolicyHandler());
                    pipeline.addLast("httpDecoder", new HttpRequestDecoder(4096, 8192, 8192, false));
                    pipeline.addLast("httpEncoder", new AsyncHttpResponseEncoder());
                    if (compressionSupported) {
                        pipeline.addLast("deflater", new HttpChunkContentCompressor());
                    }
                    if (tcpHelper.isSSL() || compressionSupported) {
                        // 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
                    }
                    pipeline.addLast("handler", new ServerHandler());
                }
            });

            addHandlers(this);
            try {
                bindFuture = bootstrap.bind(new InetSocketAddress(InetAddress.getByName(host), port));
                bindFuture.addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture channelFuture) throws Exception {
                        if (!channelFuture.isSuccess()) {
                            async.sharedHttpServers().remove(id);
                        } else {
                            Channel channel = channelFuture.channel();
                            InetSocketAddress address = (InetSocketAddress) channel.localAddress();
                            DefaultHttpServer.this.actualPort = address.getPort();
                            serverChannelGroup.add(channel);
                        }
                    }
                });
            } catch (final Throwable t) {
                // Make sure we send the exception back through the handler (if any)
                if (listenHandler != null) {
                    async.runOnContext(new VoidHandler() {
                        @Override
                        protected void handle() {
                            listenHandler.handle(new DefaultFutureResult<HttpServer>(t));
                        }
                    });
                } else {
                    // No handler - log so user can see failure
                    actualCtx.reportException(t);
                }
                listening = false;
                return this;
            }
            async.sharedHttpServers().put(id, this);
            actualServer = this;
        } else {
            // Server already exists with that host/port - we will use that
            actualServer = shared;
            this.actualPort = shared.actualPort;
            addHandlers(actualServer);
        }
        actualServer.bindFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(final ChannelFuture future) throws Exception {
                if (listenHandler != null) {
                    final AsyncResult<HttpServer> res;
                    if (future.isSuccess()) {
                        res = new DefaultFutureResult<HttpServer>(DefaultHttpServer.this);
                    } else {
                        res = new DefaultFutureResult<>(future.cause());
                        listening = false;
                    }
                    actualCtx.execute(future.channel().eventLoop(), new Runnable() {
                        @Override
                        public void run() {
                            listenHandler.handle(res);
                        }
                    });
                } else if (!future.isSuccess()) {
                    listening = false;
                    // No handler - log so user can see failure
                    actualCtx.reportException(future.cause());
                }
            }
        });
    }
    return this;
}