使用 Netty,您如何存储每个套接字连接的状态?

Ste*_*ins 4 java sockets netty

我正在使用 Netty 编写一个简单的服务器应用程序。它将接受长时间运行的套接字连接(即 telnet/ssh)...接收基于字符串的命令并发送基于字符串的响应。

我需要跟踪一些会话状态,关于该套接字连接客户端上的特定实体。我不清楚如何解决这个问题。

通道处理程序通过ChannelHandlerContext传递给其channelRead(...)方法的对象可以访问“属性”。然而,这似乎是为了在通道处理程序级别设置状态,而不是每个套接字连接级别。JavadocsAttributeMap明确指出:“请注意,[原文如此] 不可能有多个具有相同名称的键”。那里的大多数示例都将其用于简单的“计数器”插图。

ChannelLocal在早期版本的 Netty 中有一个类,这可能是相关的。但是它从 Netty 4.x 开始被删除了,我认为它也是用于处理程序级别的状态而不是连接级别的状态。

有没有办法让每个连接都有状态,同时仍然@Sharable在你的通道处理程序类上使用注释,并充分利用 Netty 的非阻塞优势?或者这个用例的方法是简单地将实例变量放在你的通道处理程序上,删除@Shareable注释,并为每个传入的连接生成一个新的连接处理程序(因此是新线程?)?

dfo*_*gni 5

Channel确实扩展了AttributeMap,所以你可以在通道上设置/获取属性。AChannel是套接字连接的抽象。

另一方面,在他们的领域中创建ChannelHandlerperChannel和 save 状态并没有错。AChannelHandler与线程无关,它们被EventLoops抽象,并且EventLoop每个Channel.

它实际上是相反的: aChannelHandler保证由同一个线程(Channel的事件循环,或将处理程序添加到 时指定的事件循环)调用Pipeline。由于这一点,您不需要同步或通道处理程序字段的 volatile 限定符。

  • 正确的!线程通常在您的应用程序启动时产生,当您创建 `EventLoopGroup` 并保持不变直到您关闭该组时。在多个 netty 引导程序之间共享组也是一种很好的做法。有一个“ThreadPerChannelEventLoop”,但它是一个例外而不是规范,并且仅在您想要进行阻塞 IO 而不是通常性能更高的异步 IO 时使用。 (3认同)