java - 在不同的上下文处理程序中使用 channel 属性

标签 java netty

我正在开发一个应用服务器,其中一部分将基于 Netty 4.0。但是,我遇到了 channel 共享变量的问题。
我读过要在我需要使用的其他上下文处理程序中使用此类变量

  • context.channel().attr(key).set()

不仅仅是

  • context.attr(key).set()

将我的变量附加到当前 channel 。
喜欢这里:

 public class HadlePackets extends ChannelInboundHandlerAdapter {

private static final Logger LOG = LoggerFactory.getLogger(HadlePackets.class);
public AttributeKey<Integer> clientIDattrKey = new AttributeKey<Integer>  ("ClientID");

@Override
public void channelRead(ChannelHandlerContext ctx, Object message) throws Exception {
 ...
ctx.channel().attr(clientIDattrKey).set(IDnum); //bind ID to channel

...
}
}

但是,我如何在处理程序的另一个上下文中检索变量的值?仍然需要属性键,我无法从附加变量的处理程序中获取它。

public class StorageHandler extends ChannelInboundHandlerAdapter{
private static final Logger LOG = LoggerFactory.getLogger(StorageSaveHandler.class);

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    Integer clientID = (Integer)ctx.channel().attr(null).get(); //How can i get proper key for this channel attribute?
    ctx.fireChannelInactive();

}

最佳答案

这应该可以工作,因为它是public static:

@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    Integer clientID = (Integer) ctx.channel().attr(HandlePackets.clientIDattrKey).get();
    ctx.fireChannelInactive();
}

这是我如何使用它的一个小例子。这只是一个代码摘录:

public class NettyServer implements Runnable {
final static AttributeKey<Long> CHECKSUMKEY = AttributeKey.valueOf("calcchecksum");
final static AttributeKey<Command> COMMANDKEY = AttributeKey.valueOf("command");
final static AttributeKey<Long> FILEHANDLEKEY = AttributeKey.valueOf("filehandle");
final static AttributeKey<File> PATHKEY = AttributeKey.valueOf("destpath");
final static AttributeKey<FileOutputStream> OUTPUTSTREAM = AttributeKey.valueOf("stream");

@Override
public void run() {
    try {
        EventLoopGroup bossGroup = new NioEventLoopGroup(BOSS_THREADS);
        EventLoopGroup workerGroup = new NioEventLoopGroup(calculateThreadCount());
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();

            // This option will allow binding to an already bound ip:port
            // combination.
            // This is usually used to be able to restart a server if it
            // crashed/got killed
            // (so while the socket is still in the TIME_WAIT state).
            bootstrap.option(ChannelOption.SO_REUSEADDR, true);
            bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast("ObjectDecoder", new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                    ch.pipeline().addLast("ObjectEncoder", new ObjectEncoder());
                    ch.pipeline().addLast("CommandHandler", new ServerCommandHandler(server, logger));
                    ch.pipeline().addLast("FileHandler", new ServerFileHandler(server, logger));
                    ch.pipeline().addLast("ChecksumHandler", new ServerChecksumHandler(server, logger));
                }
            });

            try {
                // Bind and start to accept incoming connections.
                bootstrap.bind(port).sync().channel().closeFuture().sync();
            } catch (InterruptedException e) {
                logger.debug(Message.CMDTRANSFER_INTERRUPTED_DEBUG, e.getMessage());
            }
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    } catch (Exception e) {
        logger.error(Message.CMDTRANSFER_CONNECT_ERROR, e.getMessage());
    }
}
}

如您所见,我有几个共享 channel 属性的处理程序。

public class ServerCommandHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.channel().attr(NettyServer.COMMANDKEY).set(clCommand);
        ctx.fireChannelRead(msg);
    }
}

public class ServerChecksumHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if ctx.channel().attr(NettyServer.COMMANDKEY).getAndRemove() == referenceCommand {
            //do something
        }
    }
}

关于java - 在不同的上下文处理程序中使用 channel 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25932352/

相关文章:

java - 读取另一个进程正在写入的文件

java - java.library.path中的Ktor No netty_transport_native_epoll_x86_64

netty - 哪个效率更高 : Netty's HashedWheelTimer or Quartz's scheduler?

java - io.netty.handler.ssl.OpenSsl 使用 tomcat 类而不是自身

java - 使用 JAXB 将 XML 文件解析为流

java - 在 Map of Maps 中打破 java 列表的更好方法是什么?

java - 将用户在 TimePicker 中选择的所有值放入列表中并读取它

java - 如果我的类有很多子对象,我如何初始化一个作为我的类的随机子对象的对象?

java - 构建原生镜像时如何调试 'No instances of ... are allowed in the image heap'?

request - 具有异步调用方的 Netty 同步客户端