天天看點

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變成的共享了,是以不要在裡面定義可變的屬性,否則有可能會出現安全問題。

繼續閱讀