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