简体   繁体   English

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM