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

全部评论

相关推荐

06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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