Reputation: 11870
I'm using Netty to write a simple server application. It will accept long-running socket connections (i.e. telnet/ssh)... receiving string-based commands and sending string-based responses.
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". 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". 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. 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.
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? 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?
Upvotes: 5
Views: 3137
Reputation: 1341
You should annotate your ChannelHandler
with @Sharable
then store connection-specific attributes in the ChannelHandlerContext
using attr()
. This is very well-explained in ChannelHandlerContext
documentation: "A handler can have more than one context".
Don't use ThreadPerChannelEventLoop
, it breaks the abstraction over the threading model.
Upvotes: 1
Reputation: 798
Channel
does extend AttributeMap
, so you can just set/get attributes on the channel.
A Channel
is the abstraction for a socket connection.
On the other hand, there is nothing wrong with creating a ChannelHandler
per Channel
and save state in their field. A ChannelHandler
has nothing to do with threads, those are abstracted by EventLoop
s and there is only one EventLoop
per Channel
.
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
). Thanks to this you do not need either synchronization nor the volatile qualifier for the fields of your channel handler.
Upvotes: 6