在我看来,netty有其自己的异常处理程序,并且它们不会将异常(即IOException)传播回骆驼路线。有什么办法知道客户端已断开连接?
答案 0 :(得分:2)
回答我自己的问题。 我的问题是释放客户端,这些客户端将永远等待从netty获得某种响应,主要是在处理管道期间远程主机关闭连接的情况下。
需要做的是向管道添加自定义处理程序,该处理程序应扩展ChannelDuplexHandler
并覆盖connect
并写入methods
或SimpleChannelInboundHandler
并覆盖{{1 }}。我使用了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
的{{1}}中,将此处理程序添加到管道中:
ClientInitializerFactory
在应用程序启动时会给您 initChannel
。如果像我一样需要额外的注入弹簧的bean,您最终将在工厂类中拥有几个构造函数,其中一个 pipeline.addLast(new ExceptionHandler(producer));
(带有注入的字段)调用另一个设置额外的生产者字段的