在我看来,netty 有自己的异常处理程序,并且它们不会将异常(即 IOException)传播回 Camel 路由。有什么方法可以知道客户端已断开连接吗?
最佳答案
回答我自己的问题。 我的问题是释放客户端,这些客户端将永远等待从 netty 获取某种响应,主要是在处理管道期间远程主机关闭连接的情况下。
需要做的是向管道添加一个自定义处理程序,该处理程序应扩展 ChannelDuplexHandler
并覆盖 connect
并编写 methods
或 SimpleChannelInboundHandler
并覆盖 channelInactive
。我使用了ChannelDuplexHandler。
public class ExceptionHandler extends ChannelDuplexHandler {
private final NettyProducer producer;
@Override
public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress,
ChannelPromise promise)
throws Exception {
ctx.connect(remoteAddress, localAddress, promise)
.addListener((future -> {
if (!future.isSuccess()) {
// no need to do anything here, camel will manage it on its own
}
}));
}
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
ctx.write(msg, promise).addListener(future -> {
if (!future.isSuccess()) {
reportStatusBackToCamel(ctx);
}
});
}
private void reportStatusBackToCamel(ChannelHandlerContext ctx) {
NettyCamelState nettyCamelState = producer.getCorrelationManager().getState(ctx, ctx.channel(),
new IOException());
Exchange exchange = nettyCamelState.getExchange();
AsyncCallback callback = nettyCamelState.getCallback();
exchange.setException(new RuntimeException("Client disconnected"));
callback.done(false);
}
}
如果是 SimpleChannelInboundHandler
,只需将交换处理放入 channelInactive
方法中即可。
在 initChannel
的 ClientInitializerFactory
中,将此处理程序添加到管道中:
pipeline.addLast(new ExceptionHandler(producer));
生产者
在应用程序启动时提供给您。如果您像我一样需要额外的 spring 注入(inject) bean,那么您最终只会在工厂类中拥有几个构造函数,其中一个 @Autowired (带有您注入(inject)的字段)调用另一个设置附加生产者字段。
关于java - Camel 是否可以捕获 netty 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52829251/