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