Netty 之 @Sharable

作用

       标有@Sharable的Handler,代表了他是一个可以被分享的handler,这就是说服务器注册了这个handler后,可以分享给多个客户端使用,如果没有使用该注解,则每次客户端请求时,都必须重新创建一个handler。

      

报错代码

public class NettyChannelHandler extends ChannelInitializer<SocketChannel> {

    private NettyHandler nettyHandler = new NettyHandler();

    @Override
    protected void initChannel(SocketChannel sc) throws Exception {
        sc.pipeline().addLast(nettyHandler);
}
public class NettyHandler extends SimpleChannelInboundHandler {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        //省略逻辑
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("出现错误的,关闭");
        ctx.close();
    }
}

       上述代码,在第一个客户端连接后完全没有问题,但在连接第二个客户端的时候就会出现下面的问题。

14:09:45.619 [nioEventLoopGroup-3-2] WARN io.netty.channel.ChannelInitializer - Failed to initialize a channel. 
    Closing: [id: 0xe7c2bd73, L:/127.0.0.1:9001 - R:/127.0.0.1:56799]
io.netty.channel.ChannelPipelineException: 
    com.ysw.netty_demo.Server.NettyHandler is not a @Sharable handler, so can't be added or removed multiple times.

解决

       方法一:在每次客户端连接的时候,都重新创建一个Handler。修改继承ChannelInitializer的方法即可。

public class NettyChannelHandler extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel sc) throws Exception {
        sc.pipeline().addLast(new NettyHandler());
}

       方法二:使用@Sharable注解,使得Handler变成可以共享的。这个方法直接加个注解即可。(建议使用)

@Sharable
public class NettyHandler extends SimpleChannelInboundHandler {

    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        //省略逻辑
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        System.out.println("出现错误的,关闭");
        ctx.close();
    }
}

       注:使用该方法的handler变成的共享了,所以不要在里面定义可变的属性,否则有可能会出现安全问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值