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:HttpUploadServerHandler.java

License:Apache License

private void writeResponse(Channel channel) {
    // Convert the response content to a ChannelBuffer.
    ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8);
    responseContent.setLength(0);// ww w  .ja  v  a 2  s .  co  m

    // Decide whether to close the connection or not.
    boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION))
            || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0)
                    && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase(request.headers().get(CONNECTION));

    // Build the response object.
    FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
    response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");

    if (!close) {
        // There's no need to add 'Content-Length' header
        // if this is the last response.
        response.headers().set(CONTENT_LENGTH, String.valueOf(buf.readableBytes()));
    }

    Set<Cookie> cookies;
    String value = request.headers().get(COOKIE);
    if (value == null) {
        cookies = Collections.emptySet();
    } else {
        cookies = CookieDecoder.decode(value);
    }
    if (!cookies.isEmpty()) {
        // Reset the cookies if necessary.
        for (Cookie cookie : cookies) {
            response.headers().add(SET_COOKIE, ServerCookieEncoder.encode(cookie));
        }
    }
    // Write the response.
    ChannelFuture future = channel.write(response);
    // Close the connection after the write operation is done if necessary.
    if (close) {
        future.addListener(ChannelFutureListener.CLOSE);
    }
}

From source file:MultiThreadClient.java

License:Apache License

public void run() throws Exception {
    try {/*from  w  ww  .  j  a  v  a 2s. c om*/
        Bootstrap b = new Bootstrap();
        b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true)
                .handler(new ChannelDuplexHandler() {
                    @Override
                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                        System.out.println(
                                index + "-??:" + msg + "Read:" + Thread.currentThread());
                    }

                    @Override
                    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
                            throws Exception {
                        ChannelFuture future = ctx.writeAndFlush(msg, promise);
                        System.out.println(index + "-Write:" + Thread.currentThread());
                        Thread.yield();
                        Thread.yield();
                        future.addListener(new ChannelFutureListener() {
                            @Override
                            public void operationComplete(ChannelFuture channelFuture) throws Exception {
                                System.out.println(index + "-Listener" + "Lintener:"
                                        + Thread.currentThread());
                            }
                        });
                    }
                });

        // Make the connection attempt.
        ChannelFuture f = b.connect(host, port).sync();
        for (int i = 0; i < 10; i++) {
            f.channel().writeAndFlush(Unpooled.wrappedBuffer(new byte[10]));
        }
        // Wait until the connection is closed.

        f.channel().closeFuture();
    } finally {
        //group.shutdownGracefully();
    }
}

From source file:NettyHttpTransportSourceHandler.java

License:Apache License

/**
 * activating registered handler to accept events.
 *
 * @param ctx/*from w  ww. j a va2 s .c o m*/
 * @throws Exception
 */
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {

    final Channel inboundChannel = ctx.channel();

    Bootstrap b = new Bootstrap();
    b.group(inboundChannel.eventLoop()).channel(ctx.channel().getClass());
    b.handler(new NettyTargetHandlerInitilizer(inboundChannel)).option(ChannelOption.AUTO_READ, false);

    b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    b.option(ChannelOption.TCP_NODELAY, true);
    b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 15000);

    b.option(ChannelOption.SO_SNDBUF, 1048576);
    b.option(ChannelOption.SO_RCVBUF, 1048576);

    ChannelFuture f = b.connect(NettyHttpListner.HOST, NettyHttpListner.HOST_PORT);

    outboundChannel = f.channel();
    f.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture future) throws Exception {
            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:adalightserver.http.HttpServer.java

License:Apache License

private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
    // res.headers().set("Access-Control-Allow-Methods", "POST, OPTIONS, GET");
    // res.headers().set("Access-Control-Allow-Origin", "*");
    // res.headers().set("Access-Control-Allow-Headers", "*");

    // 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);/*from  ww w  . j ava  2 s . c  o m*/
        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);
    }
}

From source file:alluxio.worker.netty.BlockDataServerHandler.java

License:Apache License

/**
 * Handles a {@link RPCBlockReadRequest} by reading the data through a {@link BlockReader}
 * provided by the block worker. This method assumes the data is available in the local storage
 * of the worker and returns an error status if the data is not available.
 *
 * @param ctx The context of this request which handles the result of this operation
 * @param req The initiating {@link RPCBlockReadRequest}
 * @throws IOException if an I/O error occurs when reading the data requested
 *//* w  w w  .  j ava  2 s. co m*/
void handleBlockReadRequest(final ChannelHandlerContext ctx, final RPCBlockReadRequest req) throws IOException {
    final long blockId = req.getBlockId();
    final long offset = req.getOffset();
    final long len = req.getLength();
    final long lockId = req.getLockId();
    final long sessionId = req.getSessionId();

    BlockReader reader = null;
    DataBuffer buffer;
    try {
        req.validate();
        reader = mWorker.readBlockRemote(sessionId, blockId, lockId);
        final long fileLength = reader.getLength();
        validateBounds(req, fileLength);
        final long readLength = returnLength(offset, len, fileLength);
        buffer = getDataBuffer(req, reader, readLength);
        RPCBlockReadResponse resp = new RPCBlockReadResponse(blockId, offset, readLength, buffer,
                RPCResponse.Status.SUCCESS);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
        future.addListener(new ClosableResourceChannelListener(reader));
        future.addListener(new ReleasableResourceChannelListener(buffer));
        mWorker.accessBlock(sessionId, blockId);
        LOG.info("Preparation for responding to remote block request for: {} done.", blockId);
    } catch (Exception e) {
        LOG.error("Exception reading block {}", blockId, e);
        RPCBlockReadResponse resp;
        if (e instanceof BlockDoesNotExistException) {
            resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE);
        } else {
            resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.UFS_READ_FAILED);
        }
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
        if (reader != null) {
            reader.close();
        }
    }
}

From source file:alluxio.worker.netty.BlockDataServerHandler.java

License:Apache License

/**
 * Handles a {@link RPCBlockWriteRequest} by writing the data through a {@link BlockWriter}
 * provided by the block worker. This method takes care of requesting space and creating the
 * block if necessary./*from www .  j  a v a 2  s  .c  o m*/
 *
 * @param ctx The context of this request which handles the result of this operation
 * @param req The initiating {@link RPCBlockWriteRequest}
 * @throws IOException if an I/O exception occurs when writing the data
 */
// TODO(hy): This write request handler is very simple in order to be stateless. Therefore, the
// block file is opened and closed for every request. If this is too slow, then this handler
// should be optimized to keep state.
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 length = req.getLength();
    final DataBuffer data = req.getPayloadDataBuffer();

    BlockWriter writer = null;
    try {
        req.validate();
        ByteBuffer buffer = data.getReadOnlyByteBuffer();

        if (offset == 0) {
            // This is the first write to the block, so create the temp block file. The file will only
            // be created if the first write starts at offset 0. This allocates enough space for the
            // write.
            mWorker.createBlockRemote(sessionId, blockId, mStorageTierAssoc.getAlias(0), length);
        } else {
            // Allocate enough space in the existing temporary block for the write.
            mWorker.requestSpace(sessionId, blockId, length);
        }
        writer = mWorker.getTempBlockWriterRemote(sessionId, blockId);
        writer.append(buffer);

        RPCBlockWriteResponse resp = new RPCBlockWriteResponse(sessionId, blockId, offset, length,
                RPCResponse.Status.SUCCESS);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
        future.addListener(new ClosableResourceChannelListener(writer));
    } catch (Exception e) {
        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 (writer != null) {
            writer.close();
        }
    }
}

From source file:alluxio.worker.netty.UnderFileSystemDataServerHandler.java

License:Apache License

/**
 * Handles a {@link RPCFileReadRequest} by reading the data through an input stream provided by
 * the file worker. This method assumes the length to read is less than or equal to the unread
 * data in the file./*  www.  j a v  a 2  s.  c om*/
 *
 * @param ctx The context of this request which handles the result of this operation
 * @param req The initiating {@link RPCFileReadRequest}
 * @throws IOException if an I/O error occurs when interacting with the UFS
 */
public void handleFileReadRequest(ChannelHandlerContext ctx, RPCFileReadRequest req) throws IOException {
    req.validate();

    long ufsFileId = req.getTempUfsFileId();
    long offset = req.getOffset();
    long length = req.getLength();
    byte[] data = new byte[(int) length];

    try {
        InputStream in = mWorker.getUfsInputStream(ufsFileId, offset);
        int bytesRead = 0;
        if (in != null) { // if we have not reached the end of the file
            while (bytesRead < length) {
                int read = in.read(data, bytesRead, (int) length - bytesRead);
                if (read == -1) {
                    break;
                }
                bytesRead += read;
            }
        }
        DataBuffer buf = bytesRead != 0 ? new DataByteBuffer(ByteBuffer.wrap(data, 0, bytesRead), bytesRead)
                : null;
        RPCFileReadResponse resp = new RPCFileReadResponse(ufsFileId, offset, bytesRead, buf,
                RPCResponse.Status.SUCCESS);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
    } catch (Exception e) {
        LOG.error("Failed to read ufs file, may have been closed due to a client timeout.", e);
        RPCFileReadResponse resp = RPCFileReadResponse.createErrorResponse(req,
                RPCResponse.Status.UFS_READ_FAILED);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
    }
}

From source file:alluxio.worker.netty.UnderFileSystemDataServerHandler.java

License:Apache License

/**
 * Handles a {@link RPCFileWriteRequest} by writing the data through an output stream provided
 * by the file worker. This method only allows appending data to the file and does not support
 * writing at arbitrary offsets./* w ww.j  av a 2s . c o m*/
 *
 * @param ctx The context of this request which handles the result of this operation
 * @param req The initiating {@link RPCFileWriteRequest}
 * @throws IOException if an I/O error occurs when interacting with the UFS
 */
public void handleFileWriteRequest(ChannelHandlerContext ctx, RPCFileWriteRequest req) throws IOException {
    long ufsFileId = req.getTempUfsFileId();
    // Currently unused as only sequential write is supported
    long offset = req.getOffset();
    long length = req.getLength();
    final DataBuffer data = req.getPayloadDataBuffer();

    try {
        OutputStream out = mWorker.getUfsOutputStream(ufsFileId);
        // This channel will not be closed because the underlying stream should not be closed, the
        // channel will be cleaned up when the underlying stream is closed.
        WritableByteChannel channel = Channels.newChannel(out);
        channel.write(data.getReadOnlyByteBuffer());
        RPCFileWriteResponse resp = new RPCFileWriteResponse(ufsFileId, offset, length,
                RPCResponse.Status.SUCCESS);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
    } catch (Exception e) {
        LOG.error("Failed to write ufs file.", e);
        RPCFileWriteResponse resp = RPCFileWriteResponse.createErrorResponse(req,
                RPCResponse.Status.UFS_WRITE_FAILED);
        ChannelFuture future = ctx.writeAndFlush(resp);
        future.addListener(ChannelFutureListener.CLOSE);
    }
}

From source file:app.WebSocketServerHandler.java

License:Apache License

private static void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
    // Generate an error page if response getStatus code is not OK (200).
    if (res.status().code() != 200) {
        ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), CharsetUtil.UTF_8);
        res.content().writeBytes(buf);//from  w  w w  .ja  v  a  2 s. co  m
        buf.release();
        HttpUtil.setContentLength(res, res.content().readableBytes());
    }

    // Send the response and close the connection if necessary.
    ChannelFuture f = ctx.channel().writeAndFlush(res);
    if (!HttpUtil.isKeepAlive(req) || res.status().code() != 200) {
        f.addListener(ChannelFutureListener.CLOSE);
    }
}

From source file:bean.lee.demo.netty.learn.http.file.HttpStaticFileServerHandler.java

License:Apache License

@Override
public void messageReceived(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
    // ????//from  w  w w.ja va 2  s.co m
    if (!request.getDecoderResult().isSuccess()) {
        sendError(ctx, BAD_REQUEST);
        return;
    }

    // ?get
    if (request.getMethod() != GET) {
        sendError(ctx, METHOD_NOT_ALLOWED);
        return;
    }

    // uri??
    final String uri = request.getUri();
    final String path = sanitizeUri(uri);
    if (path == null) {
        sendError(ctx, FORBIDDEN);
        return;
    }

    // ??
    File file = new File(path);
    if (file.isHidden() || !file.exists()) {
        sendError(ctx, NOT_FOUND);
        return;
    }

    //?
    if (file.isDirectory()) {
        if (uri.endsWith("/")) {
            sendListing(ctx, file);
        } else {
            sendRedirect(ctx, uri + '/');
        }
        return;
    }

    //?
    if (!file.isFile()) {
        sendError(ctx, FORBIDDEN);
        return;
    }

    // Cache Validation
    String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE);
    if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) {
        SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US);
        Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince);

        // Only compare up to the second because the datetime format we send
        // to the client
        // does not have milliseconds
        long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000;
        long fileLastModifiedSeconds = file.lastModified() / 1000;
        if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) {
            sendNotModified(ctx);
            return;
        }
    }

    RandomAccessFile raf;
    try {
        raf = new RandomAccessFile(file, "r");
    } catch (FileNotFoundException fnfe) {
        sendError(ctx, NOT_FOUND);
        return;
    }
    long fileLength = raf.length();

    HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
    setContentLength(response, fileLength);
    setContentTypeHeader(response, file);
    setDateAndCacheHeaders(response, file);
    if (isKeepAlive(request)) {
        response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
    }

    // Write the initial line and the header.
    ctx.write(response);

    // Write the content.
    ChannelFuture sendFileFuture;
    if (useSendFile) {
        sendFileFuture = ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength),
                ctx.newProgressivePromise());
    } else {
        sendFileFuture = ctx.write(new ChunkedFile(raf, 0, fileLength, 8192), ctx.newProgressivePromise());
    }

    sendFileFuture.addListener(new ChannelProgressiveFutureListener() {
        @Override
        public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) {
            if (total < 0) { // total unknown
                System.err.println("Transfer progress: " + progress);
            } else {
                System.err.println("Transfer progress: " + progress + " / " + total);
            }
        }

        @Override
        public void operationComplete(ChannelProgressiveFuture future) throws Exception {
            System.err.println("Transfer complete.");
        }
    });

    // Write the end marker
    ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

    // Decide whether to close the connection or not.
    if (!isKeepAlive(request)) {
        // Close the connection when the whole content is written out.
        lastContentFuture.addListener(ChannelFutureListener.CLOSE);
    }
}