What's the right way to store and retrieve session state in a NIO server?

I'm just starting out with NIO and I'm not quite sure I understand the architecture completely.

I'm writing a dummy SMTP server to be used in testing and developing programs that work with email. I get the idea of a pipeline of channel handlers, for processing a single event. I even get how channel handlers are supposed to be stateless, just working on the data that's coming in on the event they're handed. But I'm a bit confused about where in this whole system the persistent state is supposed to live.

For instance, an SMTP session might look like:

Client: connects to server
Server: "I'm a server, and I'm in the CONNECT state"
Client: "Hi, server, I'm Joe Client."
Server: "Hi, Joe, I'm ready to hear more from you."
Client: "Let's authenticate"
Server: "Sure thing. I am now in the AUTHENTICATE state"
Client: "Have some credentials."
Server: "Awesome. I am now in the COMMAND state"
Client: "Let's authenticate"
Server: "Nope, we did that already."

I get how a ChannelHandler on the server could see an incoming string of AUTH base64gobbledegook and figure out a response, but how can it know that such an event has already come through on this session?

I've seen some examples and simple tutorials that keep track of channels by the originating address, but what about a situation where there are multiple clients at the same address? For example, two different scripts running test suites, each of which might connect to the server? Originating IP address isn't granular enough.

So, is there something like a dictionary hanging around where I can say, "Please give me the stored state object for the current connection?"

1 Like

What is the lifecycle of a Channel? Does a given channel only ever process events from a single connection? And do the events generated by a single connection only ever go to a single channel? Does a channel ever get re-used, to process events for another, later connection?

This is not necessarily right. Almost all channel handlers need some state, if only to deal with buffering or message fragmentation. Some channel handlers may also have a lot of business logic in them, though that depends on the specific application.

By storing state. This is a great example of a channel handler that is stateful: some notion of connection state is required.

SocketAddress objects also store a port, and so will still be different in this case.

Nope, this is something that should be stored in a ChannelHandler or in your own object, outside the Channel entirely.




1 Like

Excellent and useful answers, thank you!

No problem, please do ask further questions if and when you have them!