[英]With Netty, how can you store state per socket connection?
I'm using Netty to write a simple server application. 我正在使用Netty编写一个简单的服务器应用程序。 It will accept long-running socket connections (ie telnet/ssh)... receiving string-based commands and sending string-based responses.
它将接受长时间运行的套接字连接(即telnet / ssh)...接收基于字符串的命令并发送基于字符串的响应。
I need to track some session state, about the particular entity on the client end of that socket connection. 我需要跟踪有关该套接字连接客户端上的特定实体的某些会话状态。 I'm unclear on how to go about this.
我不清楚该如何处理。
A channel handler, through the ChannelHandlerContext
objects passed to its channelRead(...)
method, can access "attributes". 通道处理程序通过传递到其
channelRead(...)
方法的ChannelHandlerContext
对象,可以访问“属性”。 However, this appears to be for setting state at the channel handler level , not the per socket connection level . 但是,这似乎是为了在通道处理程序级别而不是每个套接字连接级别设置状态。 The Javadocs for
AttributeMap
clearly state: " Be aware that it is not be possible [sic] to have multiple keys with the same name ". AttributeMap
的Javadocs明确指出:“ 请注意,不可能有多个具有相同名称的键 ”。 Most of the examples out there use this for simple "counter" illustrations. 那里的大多数示例都将其用于简单的“计数器”插图。
There was a ChannelLocal
class in earlier versions of Netty, that might have been relevant. Netty的早期版本中有一个
ChannelLocal
类,可能是相关的。 But it has been removed as of Netty 4.x, and I think that it too was for handler-level state rather than connection-level state. 但是从Netty 4.x开始已将其删除,我认为它也适用于处理程序级别的状态,而不是连接级别的状态。
IS there a way have per-connection state, while still using the @Sharable
annotation on your channel handler class, and taking full advantage of Netty's non-blocking benefits? 有没有一种方法可以使每个连接处于状态,同时仍在通道处理程序类上使用
@Sharable
注释,并充分利用Netty的非阻塞性优势? Or is the approach for this use case simply to place instance variables on your channel handler, drop the @Shareable
annotation, and spawn a new connection handler (and therefore new thread?) for each incoming connection? 还是这种用例的方法仅仅是将实例变量放在通道处理程序上,删除
@Shareable
批注,并为每个传入的连接生成一个新的连接处理程序(并因此产生新的线程?)?
Channel
does extend AttributeMap
, so you can just set/get attributes on the channel. Channel
确实扩展了AttributeMap
,因此您只需在通道上设置/获取属性即可。 A Channel
is the abstraction for a socket connection. Channel
是套接字连接的抽象。
On the other hand, there is nothing wrong with creating a ChannelHandler
per Channel
and save state in their field. 另一方面,为每个
Channel
创建一个ChannelHandler
并在其字段中保存状态没有错。 A ChannelHandler
has nothing to do with threads, those are abstracted by EventLoop
s and there is only one EventLoop
per Channel
. ChannelHandler
与线程无关,这些线程由EventLoop
抽象,并且每个Channel
仅一个EventLoop
。
It is actually the other way round: a ChannelHandler
is guaranteed to be called by the same thread (the Channel
's event loop, or the event loop specified when adding the handler to the Pipeline
). 实际上是另一
ChannelHandler
:确保由同一线程( Channel
的事件循环,或在将处理程序添加到Pipeline
时指定的事件循环)调用ChannelHandler
。 Thanks to this you do not need either synchronization nor the volatile qualifier for the fields of your channel handler. 因此,您不需要同步,也不需要通道处理程序的字段的volatile限定符。
You should annotate your ChannelHandler
with @Sharable
then store connection-specific attributes in the ChannelHandlerContext
using attr()
. 您应该使用
@Sharable
注释ChannelHandler
,然后使用attr()
将特定于连接的属性存储在ChannelHandlerContext
。 This is very well-explained in ChannelHandlerContext
documentation : "A handler can have more than one context". 在
ChannelHandlerContext
文档中对此进行了很好的解释:“一个处理程序可以具有多个上下文”。
Don't use ThreadPerChannelEventLoop
, it breaks the abstraction over the threading model. 不要使用
ThreadPerChannelEventLoop
,它会破坏线程模型的抽象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.