Suggestions:
- Any successful login MUST be you (because they had your login details), so … kick any OLD sessions automatically whenever someone logs in.
This has the benefit of being: simple, safe, and quickly discourages people who try logging in multiple times at once in order to cheat (I’m assuming there’s good reason why you disallow multiple simultaneous sessions from one user…). And…enforces a max of one at any one time.
Kicking session is easy, of course - just keep a hash of “login” to “SelectionKey”, and grab the key and cancel it when needed, so that it will drop out of the selector. I think you probably don’t need to explicitly close the connection if you do this - but check, just in case!
- Keep a timeout counter per SelectionKey and do the same as above (grab the key, cancel it) if no response received in X minutes. Make sure you don’t forget to put a line in the select() loop that resets the counter each time that channel is ready for READ or WRITE and has non-zero bytes ready (some Sun JVM’s still have the bug where they return a READ with -1 bytes, undocumented feature which means some form of channel disconnect).
So…you see, you really don’t need to ping. You’re getting an implicit “ping” from the client each time they send or receive data, and asssuming “no traffic in X minutes == kill you by default”. This is what I meant about, in practice, you usually don’t actually need to ping…