Netty @Sharable BUG记录
这个是昨天遇到的问题,需要将500个车的设备数据转发给另外一个平台,由于另一个平台不支持JT808协议,需要我解析完在组装成他们支持的协议
@Slf4j
@Component
public class ForwardClientHandler extends ChannelInboundHandlerAdapter {
/**
* 通道上下文信息
*/
ChannelHandlerContext ctx;
/**
* tcp链路简历成功后调用
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
log.info("----------------------tcp链路建立成功----------------------");
this.ctx = ctx;
}
/**
* 收到服务器消息后调用
*
* @throws Exception
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof ByteBuf && ctx.channel().isActive() && msg != null) {
ByteBuf buf = (ByteBuf) msg;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
if (req != null && req.length > 0) {
String body = StringUtil.bytesToHexString(req);
log.info("转发数据收到服务器回复消息---" + body);
// // 协议解析
// this.decode(ctx, req);
}
}
super.channelRead(ctx, msg);
}
/**
* 发生异常时调用
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
log.info("----------------------tcp链路发生异常----------------------");
cause.printStackTrace();
ctx.close();
}
/**
* 回复消息
*
* @param channel 接受消息的通道
* @param arr 返回的字节组
* @throws InterruptedException
*/
public void sendMsg(Channel channel, byte[] all) throws InterruptedException {
ChannelFuture future = channel.writeAndFlush(Unpooled.copiedBuffer(all)).sync();
if (!future.isSuccess()) {
log.error("发送数据出错:{}", future.cause());
}
}
}建好一个TCP长连接之后,我同是使用一个handler发送500辆车的数据,结果发生以下错误
2019-12-02 14:28:25 [WARN] [nioEventLoopGroup-2-5] - Failed to initialize a channel. Closing: [id: 0xc1f9864b]
io.netty.channel.ChannelPipelineException: com.sft.parse.forward.ForwardClientHandler is not a @Sharable handler, so can't be added or removed multiple times.
at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:587)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:199)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:392)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:379)
at com.sft.parse.forward.ForwardClient$1.initChannel(ForwardClient.java:64)
at com.sft.parse.forward.ForwardClient$1.initChannel(ForwardClient.java:55)
at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:113)
at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:105)
at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:597)
at io.netty.channel.DefaultChannelPipeline.access$000(DefaultChannelPipeline.java:44)
at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1387)
at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1122)
at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:647)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:506)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:419)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:478)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:418)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:454)
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:873)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
经过研究发现需要将handle何时能感添加@Sharable注解,将该处理器改为可共享的,也可以没发送一个车的数据new一个新的handle
查看13道真题和解析