Example usage for io.netty.channel ChannelFuture addListener

List of usage examples for io.netty.channel ChannelFuture addListener

Introduction

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

Prototype

@Override
    ChannelFuture addListener(GenericFutureListener<? extends Future<? super Void>> listener);

Source Link

Usage

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);
    }
}