我需要在客户端与Apache Camel连接断开连接时进行记录。如何检测netty-tcp断开连接?
from("{{uri.client.address}}")
答案 0 :(得分:1)
记录单个客户端断开连接有点复杂,但我会尝试分享我必须做的事情。
您需要使用自己的类扩展SimpleChannelInboundHandler并添加所需的方法。有关示例课程,请参见此处:
在那里查看我已更改为包含客户端断开连接的主要方法是:
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//command to send when there is a disconnect from client side
String command = "clientDisconnect";
if (LOG.isTraceEnabled()) {
LOG.trace("Channel closed: {}", ctx.channel());
}
LOG.info("Channel has disconnected: affects ", uniqueClientId);
//create Exchange and let the consumer process it
final Exchange exchange = consumer.getEndpoint().createExchange(ctx, command);
//create inOnly as there is no client waiting for a response
exchange.setPattern(ExchangePattern.InOnly);
// set the exchange charset property for converting
if (consumer.getConfiguration().getCharsetName() != null) {
exchange.setProperty(Exchange.CHARSET_NAME, IOHelper.normalizeCharset(consumer.getConfiguration().getCharsetName()));
}
// we want to handle the UoW
consumer.createUoW(exchange);
//set the uniqueClientId
beforeProcess(exchange, ctx, command);
processAsynchronously(exchange, ctx, command);
// to keep track of open sockets
consumer.getNettyServerBootstrapFactory().removeChannel(ctx.channel());
super.channelInactive(ctx);
}
如果频道已连接,请注意我记录的部分。
如果要为主路径中的不同客户端执行不同的操作,也可以记录不同客户端的IP地址。这应该对你有帮助。
编辑: 扩展该类后,调用扩展类TCPServerHandler。然后,您需要创建一个TCPServerHandlerFactory来引用上一个类并设置您的编码器/解码器。这个类看起来像这样:
public class TCPServerInitializerFactory extends ServerInitializerFactory {
private NettyConsumer consumer;
public TCPServerInitializerFactory(NettyConsumer consumer) {
this.consumer = consumer;
}
@Override
protected void initChannel(Channel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast("string-encoder", new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast("string-decoder", new StringDecoder(CharsetUtil.UTF_8));
**pipeline.addLast("handler", new TCPServerHandler(consumer));**
}
@Override
public ServerInitializerFactory createPipelineFactory(NettyConsumer nettyConsumer) {
return new TCPServerInitializerFactory(nettyConsumer);
}
}
标有**的行是您创建TCPServerHandler类的地方。
然后回到路线类中的驼峰,您需要将工厂添加到您的注册表中,如下所示:
TCPServerInitializerFactory serverFactory = new TCPServerInitializerFactory(null);
final CamelContext camelContext = getContext();
final org.apache.camel.impl.SimpleRegistry registry = new org.apache.camel.impl.SimpleRegistry();
final org.apache.camel.impl.CompositeRegistry compositeRegistry = new org.apache.camel.impl.CompositeRegistry();
compositeRegistry.addRegistry(camelContext.getRegistry());
compositeRegistry.addRegistry(registry);
((org.apache.camel.impl.DefaultCamelContext) camelContext).setRegistry(compositeRegistry);
registry.put("spf", serverFactory);
然后这样说:
from("netty4:tcp://0.0.0.0:3000?serverInitializerFactory=#spf&sync=true")...
现在您可能想知道,所有这些都要注册断开连接的日志。这是因为能够区分客户端断开连接并实际获取Netty代码所需的客户端IP。您可以在交易中保存一些价值,然后在您的路线中做一些事情。
答案 1 :(得分:-1)
使用ErrorHandler,例如LoggingErrorHandler:
RouteBuilder builder = new RouteBuilder() {
public void configure() {
// use logging error handler
errorHandler(loggingErrorHandler("com.mycompany.foo"));
// here is our regular route
from("{{uri.client.address}}").to("mock:out");
}
};