Hello all,

I apologize for this late reply. I finally figured out a way to implement this. As it's probably worth more than a thousand of my words, here's a code snippet that illustrates how I'm going about it:

public class NodeIoFilter extends IoFilterAdapter
{
public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception
  {
NodeContext context = (NodeContext) session.getAttribute(MinaContext.CONTEXT);
    NodeState state = context.getState();
// in these 2 application-defined states, the client is not supposed to send anything if (NodeState.SEND_INITIAL_BUNDLE.equals(state) || NodeState.SENDING_BUNDLE.equals(state))
    {
      // handle through IoHandler.exceptionCaught()
throw new ConnectException("Node " + session + " has been disconnected");
    }

    // the rest of the processing here ...
  }

  // ...
}

So basically what happens is as follows:

- each session has a limited number of possible application-defined states
- in some states the app is only reading from the client, in others it is only writing - for a "reading" state the app has performed a "session.resumeRead()" and "session.suspendWrite()" - for a "writing" state both "read" and "write" are resumed, even though we know (as per the application protocol) that it should never receive anything from the client in this state. - an idle state (in which the app should not be receiving or sending anything) is set with "read" operations resumed, knowing that it should not receive anything - when the session is in a writing or idle state, and the remote peer is disconnected or dies (for instance if I just kill it brutally), then messageReceived() is called and we infer that the client is disconnected and appropriate exception handling should occur

Using this mechanism, the server can detect a disconnected client almost in "real-time", even when it is supposed to be idle.

I hope I was clearer this time.

-Laurent

On 12/01/2010 11:18, Emmanuel Lecharny wrote:
Laurent Cohen a écrit :
Hello all,

Typically, a technique that I've implemented was using the fact that, when the remote peer is disconnected for any reason, the corresponding SelectionKey on the server becomes readable().
Even when the client hasn't sent a FIN ?
It is possible to use this when you know for example that the connection should be either idle or waiting for the server to send something. In this case, you just need to add OP_READ to the operations the key is interested in. For instance, if an idle connection becomes suddenly readable - as in SelectionKey.isReadable() - then it means it is disconnected.
Well, I would rather bet that this means something has to be read.
For this to apply, you also need to keep some state attached to the SelectionKey, so that you know that it is readable when it shouldn't.
I'm not sure I grok what you says her, but may be I need a coffee or two... (just woke up).

Reply via email to