List of usage examples for io.netty.channel ChannelFutureListener ChannelFutureListener
ChannelFutureListener
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; }