Search in sources :

Example 86 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project cradle by BingLau7.

the class ChannelOperationExamples method writingToChannel.

// 写数据并将其冲刷到远程节点这样的常规任务
public static void writingToChannel() {
    // Get the channel reference from somewhere
    Channel channel = null;
    // 创建持有要写数据的 ByteBuf
    ByteBuf buf = Unpooled.copiedBuffer("your data", CharsetUtil.UTF_8);
    // 写数据并且冲刷它
    ChannelFuture cf = channel.writeAndFlush(buf);
    // 添加 ChannelFutureListener 以便在写操作完成后接收通知
    cf.addListener(new ChannelFutureListener() {

        @Override
        public void operationComplete(ChannelFuture future) {
            if (future.isSuccess()) {
                // 写操作完成并且没有错误发生
                System.out.println("Write successful");
            } else {
                // 记录错误
                System.err.println("Write error");
                future.cause().printStackTrace();
            }
        }
    });
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) Channel(io.netty.channel.Channel) ByteBuf(io.netty.buffer.ByteBuf) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Example 87 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project riposte by Nike-Inc.

the class AccessLogEndHandler method doAccessLogging.

protected void doAccessLogging(ChannelHandlerContext ctx) throws Exception {
    if (accessLogger == null)
        return;
    HttpProcessingState httpProcessingState = ChannelAttributes.getHttpProcessingStateForChannel(ctx).get();
    if (httpProcessingState == null) {
        runnableWithTracingAndMdc(() -> logger.warn("HttpProcessingState is null. This shouldn't happen."), ctx).run();
    }
    //      logging for this request, so make sure we only do it if appropriate
    if (httpProcessingState != null && !httpProcessingState.isAccessLogCompletedOrScheduled()) {
        Instant startTime = httpProcessingState.getRequestStartTime();
        ResponseInfo responseInfo = httpProcessingState.getResponseInfo();
        HttpResponse actualResponseObject = httpProcessingState.getActualResponseObject();
        RequestInfo requestInfo = httpProcessingState.getRequestInfo();
        ChannelFutureListener doTheAccessLoggingOperation = new ChannelFutureListenerWithTracingAndMdc((channelFuture) -> accessLogger.log(requestInfo, actualResponseObject, responseInfo, Instant.now().minusMillis(startTime.toEpochMilli()).toEpochMilli()), ctx);
        //      conditions), otherwise do it when the response finishes.
        if (!httpProcessingState.isResponseSendingLastChunkSent())
            doTheAccessLoggingOperation.operationComplete(null);
        else
            httpProcessingState.getResponseWriterFinalChunkChannelFuture().addListener(doTheAccessLoggingOperation);
        httpProcessingState.setAccessLogCompletedOrScheduled(true);
    }
}
Also used : ResponseInfo(com.nike.riposte.server.http.ResponseInfo) HttpProcessingState(com.nike.riposte.server.http.HttpProcessingState) Instant(java.time.Instant) HttpResponse(io.netty.handler.codec.http.HttpResponse) ChannelFutureListenerWithTracingAndMdc(com.nike.riposte.util.asynchelperwrapper.ChannelFutureListenerWithTracingAndMdc) RequestInfo(com.nike.riposte.server.http.RequestInfo) ChannelFutureListener(io.netty.channel.ChannelFutureListener)

Example 88 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project riposte by Nike-Inc.

the class ChannelPipelineFinalizerHandler method finalizeChannelPipeline.

/**
     * This will first check the given state to see if a response was sent to the user. If not then this method will
     * send a generic error to the user so they get some response (so this method is kind of a backstop in case requests
     * somehow slip through our pipeline without being handled, which should never happen, but we have to have this just
     * in case). Then it will clean out the state so that it is ready for the next request.
     * <p/>
     * If the state indicates that a response was already sent then this method will only clean out the state for the
     * next request and will not send an error.
     */
protected void finalizeChannelPipeline(ChannelHandlerContext ctx, Object msg, HttpProcessingState state, Throwable cause) throws JsonProcessingException {
    RequestInfo<?> requestInfo = exceptionHandlingHandler.getRequestInfo(state, msg);
    //      is sent it will update the state.isResponseSent() so that further calls will return true.
    if (!state.isResponseSendingStarted()) {
        String errorMsg = "Discovered a request that snuck through without a response being sent. This should not " + "be possible and indicates a major problem in the channel pipeline.";
        logger.error(errorMsg, new Exception("Wrapper exception", cause));
        // Send a generic unhandled error response with a wrapper exception so that the logging info output by the
        //      exceptionHandlingHandler will have the overview of what went wrong.
        Exception exceptionToUse = new Exception(errorMsg, cause);
        ResponseInfo<ErrorResponseBody> responseInfo = exceptionHandlingHandler.processUnhandledError(state, msg, exceptionToUse);
        responseSender.sendErrorResponse(ctx, requestInfo, responseInfo);
    }
    ctx.flush();
    //      the metrics for this request, so make sure we only do it if appropriate.
    if (metricsListener != null && !state.isRequestMetricsRecordedOrScheduled()) {
        //      conditions), otherwise do it when the response finishes.
        if (!state.isResponseSendingLastChunkSent()) {
            // TODO: Somehow mark the state as a failed request and update the metrics listener to handle it
            metricsListener.onEvent(ServerMetricsEvent.RESPONSE_SENT, state);
        } else {
            // We need to use a copy of the state in case the original state gets cleaned.
            HttpProcessingState stateCopy = new HttpProcessingState(state);
            stateCopy.getResponseWriterFinalChunkChannelFuture().addListener((ChannelFutureListener) channelFuture -> {
                if (channelFuture.isSuccess())
                    metricsListener.onEvent(ServerMetricsEvent.RESPONSE_SENT, stateCopy);
                else {
                    metricsListener.onEvent(ServerMetricsEvent.RESPONSE_WRITE_FAILED, null);
                }
            });
        }
        state.setRequestMetricsRecordedOrScheduled(true);
    }
    // Make sure to clear out request info chunks, multipart data, and any other resources to prevent reference
    //      counting memory leaks (or any other kind of memory leaks).
    requestInfo.releaseAllResources();
    //      channel if it sits unused longer than the timeout value before the next request arrives.
    if (workerChannelIdleTimeoutMillis > 0 && ctx.pipeline().get(IDLE_CHANNEL_TIMEOUT_HANDLER_NAME) == null) {
        ctx.pipeline().addFirst(IDLE_CHANNEL_TIMEOUT_HANDLER_NAME, new IdleChannelTimeoutHandler(workerChannelIdleTimeoutMillis, "ServerWorkerChannel"));
    }
    //      request is broken. We can't do anything except kill the channel.
    if ((cause != null) && state.isResponseSendingStarted() && !state.isResponseSendingLastChunkSent()) {
        runnableWithTracingAndMdc(() -> logger.error("Received an error in ChannelPipelineFinalizerHandler after response sending was started, but " + "before it finished. Closing the channel. unexpected_error={}", cause.toString()), ctx).run();
        ctx.channel().close();
    }
}
Also used : HttpProcessingState(com.nike.riposte.server.http.HttpProcessingState) Span(com.nike.wingtips.Span) RequestInfo(com.nike.riposte.server.http.RequestInfo) LoggerFactory(org.slf4j.LoggerFactory) ChannelInboundHandler(io.netty.channel.ChannelInboundHandler) ResponseInfo(com.nike.riposte.server.http.ResponseInfo) Tracer(com.nike.wingtips.Tracer) PipelineContinuationBehavior(com.nike.riposte.server.handler.base.PipelineContinuationBehavior) ErrorResponseBody(com.nike.riposte.server.error.handler.ErrorResponseBody) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) ByteBuf(io.netty.buffer.ByteBuf) ChannelPromise(io.netty.channel.ChannelPromise) MetricsListener(com.nike.riposte.metrics.MetricsListener) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Logger(org.slf4j.Logger) ChannelOutboundHandler(io.netty.channel.ChannelOutboundHandler) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) BaseInboundHandlerWithTracingAndMdcSupport(com.nike.riposte.server.handler.base.BaseInboundHandlerWithTracingAndMdcSupport) IDLE_CHANNEL_TIMEOUT_HANDLER_NAME(com.nike.riposte.server.channelpipeline.HttpChannelInitializer.IDLE_CHANNEL_TIMEOUT_HANDLER_NAME) LastOutboundMessage(com.nike.riposte.server.channelpipeline.message.LastOutboundMessage) ChannelAttributes(com.nike.riposte.server.channelpipeline.ChannelAttributes) AsyncNettyHelper.runnableWithTracingAndMdc(com.nike.riposte.util.AsyncNettyHelper.runnableWithTracingAndMdc) ResponseSender(com.nike.riposte.server.http.ResponseSender) ProxyRouterProcessingState(com.nike.riposte.server.http.ProxyRouterProcessingState) ServerMetricsEvent(com.nike.riposte.server.metrics.ServerMetricsEvent) HttpProcessingState(com.nike.riposte.server.http.HttpProcessingState) ErrorResponseBody(com.nike.riposte.server.error.handler.ErrorResponseBody) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 89 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project async-http-client by AsyncHttpClient.

the class NettyReactiveStreamsTest method testRetryingOnFailingStream.

@Test(groups = "standalone")
public void testRetryingOnFailingStream() throws Exception {
    try (AsyncHttpClient client = asyncHttpClient()) {
        // allows us to wait until subscriber has received the first body chunk
        final CountDownLatch streamStarted = new CountDownLatch(1);
        // allows us to hold the subscriber from processing further body chunks
        final CountDownLatch streamOnHold = new CountDownLatch(1);
        // allows us to block until the request is being replayed ( this is what we want to test here!)
        final CountDownLatch replayingRequest = new CountDownLatch(1);
        // a ref to the publisher is needed to get a hold on the channel (if there is a better way, this should be changed) 
        final AtomicReference<StreamedResponsePublisher> publisherRef = new AtomicReference<>(null);
        // executing the request
        client.preparePost(getTargetUrl()).setBody(LARGE_IMAGE_BYTES).execute(new ReplayedSimpleAsyncHandler(replayingRequest, new BlockedStreamSubscriber(streamStarted, streamOnHold)) {

            @Override
            public State onStream(Publisher<HttpResponseBodyPart> publisher) {
                if (!(publisher instanceof StreamedResponsePublisher)) {
                    throw new IllegalStateException(String.format("publisher %s is expected to be an instance of %s", publisher, StreamedResponsePublisher.class));
                } else if (!publisherRef.compareAndSet(null, (StreamedResponsePublisher) publisher)) {
                    // abort on retry
                    return State.ABORT;
                }
                return super.onStream(publisher);
            }
        });
        // before proceeding, wait for the subscriber to receive at least one body chunk
        streamStarted.await();
        // The stream has started, hence `StreamedAsyncHandler.onStream(publisher)` was called, and `publisherRef` was initialized with the `publisher` passed to `onStream`
        assertTrue(publisherRef.get() != null, "Expected a not null publisher.");
        // close the channel to emulate a connection crash while the response body chunks were being received.
        StreamedResponsePublisher publisher = publisherRef.get();
        final CountDownLatch channelClosed = new CountDownLatch(1);
        getChannel(publisher).close().addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                channelClosed.countDown();
            }
        });
        // the subscriber is set free to process new incoming body chunks.
        streamOnHold.countDown();
        // the channel is confirmed to be closed
        channelClosed.await();
        // now we expect a new connection to be created and AHC retry logic to kick-in automatically
        // wait until we are notified the request is being replayed
        replayingRequest.await();
        // Change this if there is a better way of stating the test succeeded 
        assertTrue(true);
    }
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) StreamedResponsePublisher(org.asynchttpclient.netty.handler.StreamedResponsePublisher) HttpResponseBodyPart(org.asynchttpclient.HttpResponseBodyPart) AsyncHttpClient(org.asynchttpclient.AsyncHttpClient) Test(org.testng.annotations.Test) ReactiveStreamsTest(org.asynchttpclient.reactivestreams.ReactiveStreamsTest)

Example 90 with ChannelFutureListener

use of io.netty.channel.ChannelFutureListener in project iris by chicc999.

the class HandlerTask method run.

@Override
public void run() {
    // 处理请求命令
    Header header = request.getHeader();
    Command response = null;
    try {
        response = handler.process(ctx, request);
    } catch (Throwable e) {
        //如果请求需要答复
        if (request.getHeader().getAcknowledge() != Acknowledge.ACK_NO) {
            //写出响应,如果出现异常则调用exceptionCaught打印异常关闭连接
            ctx.writeAndFlush(new ErrorResponse(-1, e.getMessage(), request.getRequestId())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
        }
    }
    response.getHeader().setRequestId(request.getRequestId());
    ChannelFutureListener listenner = response.getListenner() == null ? ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE : response.getListenner();
    //服务端不处理commandCallback,直接在DispatcherHandler处理对应type.客户端则在发送时指定回调函数.
    ctx.writeAndFlush(response).addListener(listenner);
}
Also used : Header(pers.cy.iris.commons.network.protocol.Header) Command(pers.cy.iris.commons.network.protocol.Command) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ErrorResponse(pers.cy.iris.commons.network.protocol.response.ErrorResponse)

Aggregations

ChannelFutureListener (io.netty.channel.ChannelFutureListener)90 ChannelFuture (io.netty.channel.ChannelFuture)85 Channel (io.netty.channel.Channel)27 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)24 Bootstrap (io.netty.bootstrap.Bootstrap)19 Test (org.junit.Test)19 ByteBuf (io.netty.buffer.ByteBuf)18 ClosedChannelException (java.nio.channels.ClosedChannelException)17 CountDownLatch (java.util.concurrent.CountDownLatch)16 ChannelInboundHandlerAdapter (io.netty.channel.ChannelInboundHandlerAdapter)15 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)14 IOException (java.io.IOException)12 ChannelPromise (io.netty.channel.ChannelPromise)11 ConnectException (java.net.ConnectException)11 NioSocketChannel (io.netty.channel.socket.nio.NioSocketChannel)10 InetSocketAddress (java.net.InetSocketAddress)7 AtomicReference (java.util.concurrent.atomic.AtomicReference)7 AbstractChannel (io.netty.channel.AbstractChannel)6 EventLoopGroup (io.netty.channel.EventLoopGroup)6 ChannelPipeline (io.netty.channel.ChannelPipeline)4