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

全部评论

相关推荐

03-10 11:23
门头沟学院 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务