List of usage examples for io.netty.channel ChannelFuture addListener
@Override ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener);
From source file:com.ning.http.client.providers.netty_4.NettyAsyncHttpProvider.java
License:Apache License
protected final <T> void writeRequest(final Channel channel, final AsyncHttpClientConfig config, final NettyResponseFuture<T> future, final HttpRequest nettyRequest) { try {//w w w .j av a2s . c om /** * If the channel is dead because it was pooled and the remote server decided to close it, * we just let it go and the closeChannel do it's work. */ if (!channel.isOpen() || !channel.isActive()) { return; } Body body = null; if (!future.getNettyRequest().getMethod().equals(HttpMethod.CONNECT)) { BodyGenerator bg = future.getRequest().getBodyGenerator(); if (bg != null) { // Netty issue with chunking. if (InputStreamBodyGenerator.class.isAssignableFrom(bg.getClass())) { InputStreamBodyGenerator.class.cast(bg).patchNettyChunkingIssue(true); } try { body = bg.createBody(); } catch (IOException ex) { throw new IllegalStateException(ex); } long length = body.getContentLength(); if (length >= 0) { nettyRequest.headers().set(HttpHeaders.Names.CONTENT_LENGTH, length); } else { nettyRequest.headers().set(HttpHeaders.Names.TRANSFER_ENCODING, HttpHeaders.Values.CHUNKED); } } else { body = null; } } if (TransferCompletionHandler.class.isAssignableFrom(future.getAsyncHandler().getClass())) { FluentCaseInsensitiveStringsMap h = new FluentCaseInsensitiveStringsMap(); for (String s : future.getNettyRequest().headers().names()) { for (String header : future.getNettyRequest().headers().getAll(s)) { h.add(s, header); } } TransferCompletionHandler.class.cast(future.getAsyncHandler()).transferAdapter( new NettyTransferAdapter(h, nettyRequest.getContent(), future.getRequest().getFile())); } // Leave it to true. if (future.getAndSetWriteHeaders(true)) { try { channel.write(nettyRequest) .addListener(new ProgressListener(true, future.getAsyncHandler(), future)); } catch (Throwable cause) { log.debug(cause.getMessage(), cause); try { channel.close(); } catch (RuntimeException ex) { log.debug(ex.getMessage(), ex); } return; } } if (future.getAndSetWriteBody(true)) { if (!future.getNettyRequest().getMethod().equals(HttpMethod.CONNECT)) { if (future.getRequest().getFile() != null) { final File file = future.getRequest().getFile(); long fileLength = 0; final RandomAccessFile raf = new RandomAccessFile(file, "r"); try { fileLength = raf.length(); ChannelFuture writeFuture; if (channel.pipeline().get(SslHandler.class) != null) { writeFuture = channel.write(new ChunkedFile(raf, 0, fileLength, 8192)); } else { final FileRegion region = new OptimizedFileRegion(raf, 0, fileLength); writeFuture = channel.write(region); } writeFuture.addListener(new ProgressListener(false, future.getAsyncHandler(), future)); } catch (IOException ex) { if (raf != null) { try { raf.close(); } catch (IOException e) { } } throw ex; } } else if (body != null || future.getRequest().getParts() != null) { /** * TODO: AHC-78: SSL + zero copy isn't supported by the MultiPart class and pretty complex to implements. */ if (future.getRequest().getParts() != null) { String boundary = future.getNettyRequest().headers().get("Content-Type"); String length = future.getNettyRequest().headers().get("Content-Length"); body = new MultipartBody(future.getRequest().getParts(), boundary, length); } ChannelFuture writeFuture; if (channel.pipeline().get(SslHandler.class) == null && (body instanceof RandomAccessBody)) { BodyFileRegion bodyFileRegion = new BodyFileRegion((RandomAccessBody) body); writeFuture = channel.write(bodyFileRegion); } else { BodyChunkedInput bodyChunkedInput = new BodyChunkedInput(body); BodyGenerator bg = future.getRequest().getBodyGenerator(); if (bg instanceof FeedableBodyGenerator) { ((FeedableBodyGenerator) bg).setListener(new FeedListener() { @Override public void onContentAdded() { channel.pipeline().get(ChunkedWriteHandler.class).resumeTransfer(); } }); } writeFuture = channel.write(bodyChunkedInput); } final Body b = body; writeFuture.addListener(new ProgressListener(false, future.getAsyncHandler(), future) { public void operationComplete(ChannelFuture cf) { try { b.close(); } catch (IOException e) { log.warn("Failed to close request body: {}", e.getMessage(), e); } super.operationComplete(cf); } }); } } } } catch (Throwable ioe) { try { channel.close(); } catch (RuntimeException ex) { log.debug(ex.getMessage(), ex); } } try { future.touch(); int requestTimeout = AsyncHttpProviderUtils.requestTimeout(config, future.getRequest()); if (requestTimeout != -1 && !future.isDone() && !future.isCancelled()) { ReaperFuture reaperFuture = new ReaperFuture(future); Future<?> scheduledFuture = config.reaper().scheduleAtFixedRate(reaperFuture, 0, requestTimeout, TimeUnit.MILLISECONDS); reaperFuture.setScheduledFuture(scheduledFuture); future.setReaperFuture(reaperFuture); } } catch (RejectedExecutionException ex) { abort(future, ex); } }
From source file:com.ning.http.client.providers.netty_4.NettyAsyncHttpProvider.java
License:Apache License
private <T> ListenableFuture<T> doConnect(final Request request, final AsyncHandler<T> asyncHandler, NettyResponseFuture<T> f, boolean useCache, boolean asyncConnect, boolean reclaimCache) throws IOException { if (isClose.get()) { throw new IOException("Closed"); }//w w w. j av a 2 s . c o m if (request.getUrl().startsWith(WEBSOCKET) && !validateWebSocketRequest(request, asyncHandler)) { throw new IOException("WebSocket method must be a GET"); } ProxyServer proxyServer = ProxyUtils.getProxyServer(config, request); boolean useProxy = proxyServer != null; URI uri; if (useRawUrl) { uri = request.getRawURI(); } else { uri = request.getURI(); } Channel channel = null; if (useCache) { if (f != null && f.reuseChannel() && f.channel() != null) { channel = f.channel(); } else { URI connectionKeyUri = useProxy ? proxyServer.getURI() : uri; channel = lookupInCache(connectionKeyUri, request.getConnectionPoolKeyStrategy()); } } ByteBuf bufferedBytes = null; if (f != null && f.getRequest().getFile() == null && !f.getNettyRequest().getMethod().name().equals(HttpMethod.CONNECT.name())) { bufferedBytes = f.getNettyRequest().data(); } boolean useSSl = isSecure(uri) && !useProxy; if (channel != null && channel.isOpen() && channel.isActive()) { HttpRequest nettyRequest = buildRequest(config, request, uri, f == null ? false : f.isConnectAllowed(), bufferedBytes, proxyServer); if (f == null) { f = newFuture(uri, request, asyncHandler, nettyRequest, config, this, proxyServer); } else { nettyRequest = buildRequest(config, request, uri, f.isConnectAllowed(), bufferedBytes, proxyServer); f.setNettyRequest(nettyRequest); } f.setState(NettyResponseFuture.STATE.POOLED); f.attachChannel(channel, false); log.debug("\nUsing cached Channel {}\n for request \n{}\n", channel, nettyRequest); channel.pipeline().context(NettyAsyncHttpProvider.class).attr(DEFAULT_ATTRIBUTE).set(f); try { writeRequest(channel, config, f, nettyRequest); } catch (Exception ex) { log.debug("writeRequest failure", ex); if (useSSl && ex.getMessage() != null && ex.getMessage().contains("SSLEngine")) { log.debug("SSLEngine failure", ex); f = null; } else { try { asyncHandler.onThrowable(ex); } catch (Throwable t) { log.warn("doConnect.writeRequest()", t); } IOException ioe = new IOException(ex.getMessage()); ioe.initCause(ex); throw ioe; } } return f; } // Do not throw an exception when we need an extra connection for a redirect. if (!reclaimCache && !connectionsPool.canCacheConnection()) { IOException ex = new IOException("Too many connections " + config.getMaxTotalConnections()); try { asyncHandler.onThrowable(ex); } catch (Throwable t) { log.warn("!connectionsPool.canCacheConnection()", t); } throw ex; } boolean acquiredConnection = false; if (trackConnections) { if (!reclaimCache) { if (!freeConnections.tryAcquire()) { IOException ex = new IOException("Too many connections " + config.getMaxTotalConnections()); try { asyncHandler.onThrowable(ex); } catch (Throwable t) { log.warn("!connectionsPool.canCacheConnection()", t); } throw ex; } else { acquiredConnection = true; } } } NettyConnectListener<T> c = new NettyConnectListener.Builder<T>(config, request, asyncHandler, f, this, bufferedBytes).build(uri); boolean avoidProxy = ProxyUtils.avoidProxy(proxyServer, uri.getHost()); if (useSSl) { constructSSLPipeline(c); } ChannelFuture channelFuture; Bootstrap bootstrap = request.getUrl().startsWith(WEBSOCKET) ? (useSSl ? secureWebSocketBootstrap : webSocketBootstrap) : (useSSl ? secureBootstrap : plainBootstrap); bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, config.getConnectionTimeoutInMs()); try { InetSocketAddress remoteAddress; if (request.getInetAddress() != null) { remoteAddress = new InetSocketAddress(request.getInetAddress(), AsyncHttpProviderUtils.getPort(uri)); } else if (proxyServer == null || avoidProxy) { remoteAddress = new InetSocketAddress(AsyncHttpProviderUtils.getHost(uri), AsyncHttpProviderUtils.getPort(uri)); } else { remoteAddress = new InetSocketAddress(proxyServer.getHost(), proxyServer.getPort()); } if (request.getLocalAddress() != null) { channelFuture = bootstrap.connect(remoteAddress, new InetSocketAddress(request.getLocalAddress(), 0)); } else { channelFuture = bootstrap.connect(remoteAddress); } } catch (Throwable t) { if (acquiredConnection) { freeConnections.release(); } abort(c.future(), t.getCause() == null ? t : t.getCause()); return c.future(); } boolean directInvokation = true; if (IN_IO_THREAD.get() && DefaultChannelFuture.isUseDeadLockChecker()) { directInvokation = false; } if (directInvokation && !asyncConnect && request.getFile() == null) { int timeOut = config.getConnectionTimeoutInMs() > 0 ? config.getConnectionTimeoutInMs() : Integer.MAX_VALUE; if (!channelFuture.awaitUninterruptibly(timeOut, TimeUnit.MILLISECONDS)) { if (acquiredConnection) { freeConnections.release(); } channelFuture.cancel(); abort(c.future(), new ConnectException(String.format("Connect operation to %s timeout %s", uri, timeOut))); } try { c.operationComplete(channelFuture); } catch (Exception e) { if (acquiredConnection) { freeConnections.release(); } IOException ioe = new IOException(e.getMessage()); ioe.initCause(e); try { asyncHandler.onThrowable(ioe); } catch (Throwable t) { log.warn("c.operationComplete()", t); } throw ioe; } } else { channelFuture.addListener(c); } log.debug("\nNon cached request \n{}\n\nusing Channel \n{}\n", c.future().getNettyRequest(), channelFuture.getChannel()); if (!c.future().isCancelled() || !c.future().isDone()) { openChannels.add(channelFuture.channel()); c.future().attachChannel(channelFuture.channel(), false); } return c.future(); }
From source file:com.nus.mazegame.client.GameClientHandler.java
@Override public void channelActive(final ChannelHandlerContext ctx) { this.ctx = ctx; if (rsender == null) { rsender = new RetrySender(instance); ui.init();/*ww w. jav a 2s .c o m*/ } ChannelFuture closeFuture = ctx.channel().closeFuture(); closeFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { System.out.println("Master lost, connect to slave..."); GameClient.init(GameInfo.instance.getSlaveAddr(), GameInfo.instance.getHostPort() + 1, MNodeType.CLIENT, ctx.channel().localAddress()); } }); }
From source file:com.nus.mazegame.client.GameClientHandler.java
public void write(byte[] buff, boolean closeCtx) { final ChannelFuture f = ctx.writeAndFlush(buff); if (closeCtx) { f.addListener(closeFutureListener); }/*from w w w.jav a2s . c o m*/ }
From source file:com.nus.mazegame.server.GameServerHandler.java
@Override public void channelActive(final ChannelHandlerContext ctx) { synchronized (instance) { if (rsender == null) { // when client connect to this slave, means master failed if (GameService.gameService.isIsSlave()) { Logger.getLogger(GameServerHandler.class.getName()).log(Level.INFO, "Master lost..."); new Thread() { @Override//from ww w .j a v a2 s .c om public void run() { try { GameService.gameService.end(GameService.gameService.getMasterId()); GameService.gameService.promoteSlave(); GameService.gameService.changeSlave(); } catch (Exception ex) { Logger.getLogger(GameService.class.getName()).log(Level.SEVERE, null, ex); } } }.start(); } rsender = new RetrySender(instance); } } String clientSocketAddr = ((InetSocketAddress) ctx.channel().remoteAddress()).toString(); Logger.getLogger(GameServerHandler.class.getName()).log(Level.INFO, "New user connected...{0}", clientSocketAddr); CNameChannelMap.putIfAbsent(clientSocketAddr, ctx); CName = clientSocketAddr; clientAddr = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostName(); addressBook.putIfAbsent(clientSocketAddr, clientAddr); ChannelFuture closeFuture = ctx.channel().closeFuture(); closeFuture.addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (userId == GameService.gameService.getMasterId()) { Logger.getLogger(GameServerHandler.class.getName()).log(Level.SEVERE, "Master server failed but client still alive..."); } else if (userId == GameService.gameService.getSlaveId()) { Logger.getLogger(GameServerHandler.class.getName()).log(Level.INFO, "Slave node lost...userId:{0}", userId); // this case when slave dead new Thread() { @Override public void run() { try { GameService.gameService.end(userId); GameService.gameService.changeSlave(); } catch (Exception ex) { Logger.getLogger(GameService.class.getName()).log(Level.SEVERE, null, ex); } } }.start(); } else { Logger.getLogger(GameServerHandler.class.getName()).log(Level.INFO, "Client node lost...userId:{0}", userId); GameService.gameService.end(userId); MsgHeader header = new MsgHeader(); header.setUserId(userId); GeneralResponsePacket endPacket = new GeneralResponsePacket(); endPacket.setType(GeneralResponseType.END); endPacket.setStatus(ResponseStatus.SUCCESS); String msgId3 = RetrySender.genMsgKey(GameService.gameService.getMasterId()); header.setMsgId(msgId3); header.setAction(Command.UPDATE_END); SendPacketTask task2 = new SendPacketTask(header.getMsgId(), header, endPacket); task2.setCloseCtx(false); rsender.send(task2); } } }); }
From source file:com.nus.mazegame.server.GameServerHandler.java
public void sendMsg(final ChannelHandlerContext ctx, byte[] msg, boolean closeCtx) { final ChannelFuture f = ctx.writeAndFlush(msg); if (closeCtx) { f.addListener(new ChannelFutureListener() { @Override//from w w w . j a v a 2 s .co m public void operationComplete(ChannelFuture future) { assert f == future; ctx.close(); } }); } }
From source file:com.ociweb.pronghorn.adapter.netty.impl.HttpStaticFileServerHandler.java
License:Apache License
public static void progressAndClose(FullHttpRequest request, ChannelFuture sendFileFuture, ChannelFuture lastContentFuture) { sendFileFuture.addListener(new ChannelProgressiveFutureListener() { @Override//from w w w .j a v a 2 s . co m public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) { if (total < 0) { // total unknown System.err.println(future.channel() + " Transfer progress: " + progress); } else { System.err.println(future.channel() + " Transfer progress: " + progress + " / " + total); } } @Override public void operationComplete(ChannelProgressiveFuture future) { System.err.println(future.channel() + " Transfer complete."); } }); // Decide whether to close the connection or not. if (!HttpUtil.isKeepAlive(request)) { // Close the connection when the whole content is written out. lastContentFuture.addListener(ChannelFutureListener.CLOSE); } }
From source file:com.onion.worker.WorkerDataServerHandler.java
License:Apache License
private void handleBlockReadRequest(final ChannelHandlerContext ctx, final RPCBlockReadRequest req) { final long blockId = req.getBlockId(); final long offset = req.getOffset(); long readLength = req.getLength(); String readFilePath = backendDir.getAbsolutePath() + "/" + blockId; if (!new File(readFilePath).exists()) { RPCBlockReadResponse resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.UNKNOWN_MESSAGE_ERROR); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); return;//from w w w. j a v a 2s. com } BlockReader blockReader = null; try { blockReader = new LocalFileBlockReader(readFilePath); req.validate(); final long fileLength = blockReader.getLength(); validateBounds(req, fileLength); readLength = returnLength(offset, readLength, fileLength); DataBuffer dataBuffer = getDataBuffer(req, blockReader, readLength); RPCBlockReadResponse resp = new RPCBlockReadResponse(blockId, offset, readLength, dataBuffer, RPCResponse.Status.SUCCESS); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); future.addListener(new ClosableResourceChannelListener(blockReader)); } catch (IOException e) { e.printStackTrace(); RPCBlockReadResponse resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); if (blockReader != null) { try { blockReader.close(); } catch (IOException e1) { e1.printStackTrace(); } } } }
From source file:com.onion.worker.WorkerDataServerHandler.java
License:Apache License
private void handleBlockWriteRequest(final ChannelHandlerContext ctx, final RPCBlockWriteRequest req) throws IOException { final long sessionId = req.getSessionId(); final long blockId = req.getBlockId(); final long offset = req.getOffset(); final long writeLength = req.getLength(); final DataBuffer data = req.getPayloadDataBuffer(); BlockWriter blockWriter = null;/* w ww .j a v a 2 s . co m*/ if (!backendDir.exists() && backendDir.mkdirs()) { throw new IOException("Backend directory does not exist"); } try { blockWriter = new LocalFileBlockWriter(backendDir.getAbsolutePath() + "/" + blockId); req.validate(); ByteBuffer buffer = data.getReadOnlyByteBuffer(); blockWriter.append(buffer); RPCBlockWriteResponse resp = new RPCBlockWriteResponse(sessionId, blockId, offset, writeLength, RPCResponse.Status.SUCCESS); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); } catch (IOException e) { e.printStackTrace(); LOG.error("Error writing remote block : {}", e.getMessage(), e); RPCBlockWriteResponse resp = RPCBlockWriteResponse.createErrorResponse(req, RPCResponse.Status.WRITE_ERROR); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); if (blockWriter != null) { blockWriter.close(); } } }
From source file:com.ottogroup.bi.spqr.websocket.server.SPQRWebSocketServerHandler.java
License:Apache License
/** * Sends a {@link HttpResponse} according to prepared {@link FullHttpResponse} to the client. The * code was copied from netty.io websocket server example. The origins may be found at: * {@linkplain https://github.com/netty/netty/blob/4.0/example/src/main/java/io/netty/example/http/websocketx/server/WebSocketServerHandler.java} * @param ctx// w w w.ja v a2 s. c o m * @param req * @param res */ private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) { // Generate an error page if response getStatus code is not OK (200). if (res.getStatus().code() != 200) { ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8); res.content().writeBytes(buf); buf.release(); HttpHeaders.setContentLength(res, res.content().readableBytes()); } // Send the response and close the connection if necessary. ChannelFuture f = ctx.channel().writeAndFlush(res); if (!HttpHeaders.isKeepAlive(req) || res.getStatus().code() != 200) { f.addListener(ChannelFutureListener.CLOSE); } }