【发布时间】:2018-10-16 22:51:51
【问题描述】:
在我看来,netty 有自己的异常处理程序,它们不会将异常(即 IOException)传播回骆驼路线。有什么方法可以知道客户端已断开连接?
【问题讨论】:
标签: java apache-camel
在我看来,netty 有自己的异常处理程序,它们不会将异常(即 IOException)传播回骆驼路线。有什么方法可以知道客户端已断开连接?
【问题讨论】:
标签: java apache-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));
producer 在应用程序启动时提供给您。如果您像我一样需要额外的 spring 注入 bean,那么您最终会在您的工厂类中拥有几个构造函数,一个 @Autowired(带有您注入的字段)调用另一个设置额外的生产者字段。
【讨论】: