Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (741)
Games in Android Showcase (225)
games submitted by our members
Games in WIP (823)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  NIO SocketChannel Timeout  (Read 4686 times)
0 Members and 1 Guest are viewing this topic.
Offline elias

Senior Devvie





« Posted 2004-12-10 11:14:03 »

Hi,

The Tribal Trouble matchmaking service uses NIO selectors with non-blocking SocketChannels. However, I've discovered that pulling the network cable from a connected client won't result in an error on the corresponding SelectionKey on the service. I've tried the socket().setSoTimeout(value) call (combined with a socket().setKeepAlive()), but it only seems to work on win32, not linux. I'd expect to get notifications of timeouts, like I get notifications of proper closing of the channel from the other end.

What is the preferred way of detecting such error conditions? I'd really like not to have to implement manual ping as that requires a periodic wakeup and fiddly code.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #1 - Posted 2004-12-10 11:36:21 »

Off the top of my head...

1. This is the subject of outstanding bug reports (c.f. bug parade - differeing behaviour on timeout; e.g. IIRC windows has oscillated back and forth between doing something and doing nothing)

2. This is the subject of outstanding RFE's (ditto - but requests for extra granularity on the selectors, e.g. "add a TIMEOUT event")

3. Bear in mind that it is common for a TCP connection to be disconnected *accidentally* and *for no error to be thrown* and for it to be reconnected again, transparently. For instance, telnet to a server, pull your network cable (don't type anything!), wait a few minutes, plug it back in again, and you *should* find you're still connected, still logged-in, etc. I've seen a TCP connection survive hours this way before. But...I can't remember if that's what the spec demands, or if it's just that a lot of TCP stacks happen to implement it this way when they shouldn't.

4. Quite a few bugs in this area were fixed in *each* of moving from 1.4.0 to .1 and to .2 and even in the _XX releases. So, evidence suggests it's an active area of patching by Sun at the moment.

As to how you deal with it...you ping.

In practice, you shouldn't need to ping much, most of the time you don't care if a connection has idled away until/unless you're going to send it some information or ask it something anyway. If you could provide your use-case for why you need to know it's status, I might be able to provide a more helpful answer.

Finally, note that java has historically been very poor at handling timeouts and disconnects on all forms of networking (java.io, java.nio, etc). It's been broken in many different ways across most platforms most of the time, so for now it's still an area where manual hacking is necessary.

malloc will be first against the wall when the revolution comes...
Offline elias

Senior Devvie





« Reply #2 - Posted 2004-12-10 11:53:24 »

Thank you for the thorough reply. The exact reason I discovered the bug is because the matchmaking service implements one-login-per-user so for example the user "elias" can only be logged in from one TT client. I had a hard crashing session while logged in, and discovered that the service kicked me the second time I tried to log in with the same user even though it was a while since the old session crashed.

To avoid this situation (and leaking connections in general for a very long running server), how do I implement pinging? I have this really nice and simple Selector.select(), but I guess this has to be timed out regularly and the connections pinged. And I probably can't ping all of them at the same time and thereby risking a "hiccup" when (potentially) thousands of clients are connected. What a mess.

- elias

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #3 - Posted 2004-12-10 12:11:36 »

Suggestions:

1. 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!

2. 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...

malloc will be first against the wall when the revolution comes...
Offline elias

Senior Devvie





« Reply #4 - Posted 2004-12-10 17:23:56 »

Well I ended up with some primitive form of ping anyway, since the hard part was really the timer - waking up from select() once in a while and locate the timed out connections. The actual pinging (sending keep alive data once in a while) was simple.

- elias

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #5 - Posted 2004-12-10 17:52:35 »

Quote
Well I ended up with some primitive form of ping anyway, since the hard part was really the timer - waking up from select() once in a while and locate the timed out connections. The actual pinging (sending keep alive data once in a while) was simple.

- elias


I don't quite understand - why do you need to "wake up" from a select?

malloc will be first against the wall when the revolution comes...
Offline elias

Senior Devvie





« Reply #6 - Posted 2004-12-11 04:49:31 »

Well the service is entirely single-threaded, so I figured the only way to get at those timed out connections, the thread needs to "wake up" from select() once in a while.

- elias

Online princec

« JGO Spiffy Duke »


Medals: 974
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #7 - Posted 2004-12-11 10:04:13 »

The default socket timeout is something like 4 hours or something isn't it? It's far longer than you expect it to be that's for certain.

Blah3's suggestion of kicking existing sessions on subsequent login is easily the best idea.

Cas Smiley

Pages: [1]
  ignore  |  Print  
 
 

 
Ecumene (110 views)
2017-09-30 02:57:34

theagentd (136 views)
2017-09-26 18:23:31

cybrmynd (245 views)
2017-08-02 12:28:51

cybrmynd (241 views)
2017-08-02 12:19:43

cybrmynd (239 views)
2017-08-02 12:18:09

Sralse (254 views)
2017-07-25 17:13:48

Archive (864 views)
2017-04-27 17:45:51

buddyBro (1008 views)
2017-04-05 03:38:00

CopyableCougar4 (1568 views)
2017-03-24 15:39:42

theagentd (1373 views)
2017-03-24 15:32:08
List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05

SF/X Libraries
by SkyAphid
2017-03-02 06:38:56

SF/X Libraries
by SkyAphid
2017-03-02 06:38:32

SF/X Libraries
by SkyAphid
2017-03-02 06:38:05

SF/X Libraries
by SkyAphid
2017-03-02 06:37:51
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!