Netty Sharable Handler 使用是私有变量

Netty Sharable Handler 使用是私有变量

netty中Sharable handler的定义如下
http://netty.io/4.0/api/io/netty/channel/ChannelHandler.Sharable.html

我们不用每次都创建handler,例如下面的代码

    public class InitChannel extends ChannelInitializer<SocketChannel> {
    private final MessageEncoder messageEncoder = new MessageEncoder();

    @Override
    public void initChannel(SocketChannel socketChannel) throws Exception {
        ChannelPipeline p = socketChannel.pipeline();
        p.addLast(new JsonObjectDecoder());
        p.addLast(messageEncoder);
    }
  }

其中messageEncoder就是一个sharable handler,而上面的JsonObjectdecoder不是一个sharable handler,从这里能够看到每次建立的channel时候都需要new 一个JsonObjectDecoder.而messageEncoder不需要。

但是,我们在使用sharable handler的时候,希望知道这个channel是对应的是哪个client的,希望把clientId记录下来。

@ChannelHandler.Sharable
public class SharedHander extends ChannelInboundHandlerAdapter {

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(SharedHander.class);
    private String client;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        String s = (String)msg;
        if (s.contains("firstMessage")) {
            client = s;
        } else {
            logger.info("client-private: " + client + "\n receive: " + s);
        }
    }
}

我们利用多个客户端进行发送的时候
打印log 如下

十一月 24, 2015 11:28:42 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private:   firstMessagedeviceId2sendMessage--deviceId2
 receive:  sendMessage--deviceId2
十一月 24, 2015 11:28:42 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private:   firstMessagedeviceId2sendMessage--deviceId2
 receive:  sendMessage--deviceId1
十一月 24, 2015 11:28:47 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private:   firstMessagedeviceId2sendMessage--deviceId2
 receive:  sendMessage--deviceId1
十一月 24, 2015 11:28:47 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private:   firstMessagedeviceId2sendMessage--deviceId2
 receive:  sendMessage--deviceId2

可以看出来,无论是那个device发送的,最后结果都是deviceId2,因为是sharable的时候,多个channel会共享这个变量。

那么如果想保存自己的 channelId 需要怎么做呢?
我们参考下面的官方文档
http://netty.io/4.0/api/io/netty/channel/ChannelHandler.html

代码修改如下:

    private static final InternalLogger logger = InternalLoggerFactory.getInstance(SharedHander.class);
    private final AttributeKey<String> clientKey =
            AttributeKey.valueOf("client");
    private String client;
 @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        Attribute<String> attr = ctx.attr(clientKey);
        String s = (String)msg;
        if (s.contains("firstMessage")) {
            client = s;
            attr.set(s);
        } else {
            logger.info("client-private: " + client + "\n receive: " + s);
            //logger.info("client-key: " + attr.get()+" \n receive :" + s);
        }
    }

我们再一次看下log:


十一月 24, 2015 11:34:36 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private: firstMessagedeviceId1sendMessage--deviceId1
receive: sendMessage--deviceId2
十一月 24, 2015 11:34:36 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-key: firstMessagedeviceId2sendMessage--deviceId2
receive :sendMessage--deviceId2
十一月 24, 2015 11:34:36 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-private: firstMessagedeviceId1sendMessage--deviceId1
receive: sendMessage--deviceId1
十一月 24, 2015 11:34:36 上午 com.destinym.nettystudy.handler.sharehandlerdifferentvariable.SharedHander channelRead
信息: client-key: firstMessagedeviceId1sendMessage--deviceId1
receive :sendMessage--deviceId1

看出来,使用attr能够得到我们想要的结果。
(注意对于private string client的内容,和最后赋值的客户端有关系)

全部代码可以在下面下载
https://github.com/destinym/netty.git

你可能感兴趣的:(netty)