我正在使用Netty编写一个简单的服务器应用程序。它将接受长时间运行的套接字连接(即telnet / ssh)...接收基于字符串的命令并发送基于字符串的响应。
我需要跟踪一些会话状态,关于该套接字连接的客户端上的特定实体。我不清楚如何解决这个问题。
通过传递给ChannelHandlerContext
方法的channelRead(...)
对象,通道处理程序可以访问“属性”。但是,这似乎是用于设置通道处理程序级别的状态,而不是每个套接字连接级别。 AttributeMap
的Javadoc明确指出:“请注意,[sic]不可能有多个具有相同名称的密钥”。大多数例子都是用于简单的“反”插图。
早期版本的Netty中有一个ChannelLocal
类,可能是相关的。但它已经从Netty 4.x中删除了,我认为它也适用于处理程序级别的状态而不是连接级别状态。
是否有一种方式具有每个连接状态,同时仍然在您的频道处理程序类上使用@Sharable
注释,并充分利用Netty的非阻塞优势?或者这个用例的方法是简单地将实例变量放在您的通道处理程序上,删除@Shareable
注释,并为每个传入连接生成一个新的连接处理程序(以及新的线程?)?
答案 0 :(得分:4)
Channel
确实扩展了AttributeMap
,因此您只需在频道上设置/获取属性即可。
Channel
是套接字连接的抽象。
另一方面,创建ChannelHandler
每Channel
并在其字段中保存状态没有任何问题。 ChannelHandler
与线程无关,它们由EventLoop
抽象,每EventLoop
只有一个Channel
。
实际上反过来说:ChannelHandler
保证由同一个线程(Channel
的事件循环或添加处理程序时指定的事件循环调用到Pipeline
)。多亏了这一点,您不需要同步也不需要使用volatile限定符来处理通道处理程序的字段。
答案 1 :(得分:0)
您应该用ChannelHandler
注释@Sharable
,然后使用ChannelHandlerContext
将特定于连接的属性存储在attr()
中。 ChannelHandlerContext
documentation中对此进行了很好的解释:“一个处理程序可以具有多个上下文”。
不要使用ThreadPerChannelEventLoop
,它会破坏线程模型的抽象性。