1

I have a server with NIO realization with selector. The realization is rather simple:

            selector.select();
            Set<SelectionKey> keys = selector.selectedKeys();
            for (SelectionKey key : keys) {
                if (! key.isValid()) {
                    continue;
                }
                UserConnection connection = users.get(key);
                if (key.isReadable()) {
                    processReadableKey(key, connection);
                } else if (key.isWritable()) {
                    processWritableKey(key, connection);
                }

The thing is, when two packets (messages) arrives one after another almost immediately, selector reacts and processes the first one, but then it does not reacts and marks the corresponding key as "readable" to handle the second one. When the next message arrives, selector handles it and after that it processes that "lost" packet. I don't know, how to fix it. I tried to reduce channel buffer, and i tried to wake up selector by selector.wakeup(), but it did not help, because the problem is connected with recognizing the key as "readable" immediately after hanling the first message in the couple. Any ideas?

Luo
  • 445
  • 2
  • 10
  • nio code is notoriously difficult to get exactly right. it's a very tricky api. unless you are required to do this for a class, i'd go with a framework like netty which hides this complexity under the hood. – jtahlborn May 03 '15 at 22:16
  • Selector doesn't miss events. Are you sure two packets really arrived? – user207421 May 04 '15 at 01:17

1 Answers1

0

Sounds like you need to remove selection keys from the selected keys set before using them. If you don't do this, when you call selectedKeys(), the set returned will still contain the old, used keys.

Something along the lines of:

 Iterator iter = selector.selectedKeys().iterator();  
 while (iter.hasNext()) {  
     SelectionKey key = (SelectionKey) iter.next();  
     iter.remove();  // remove here 
     process(key);  
 }
Chris Dennett
  • 22,412
  • 8
  • 58
  • 84
  • I do remove them, infortunately, I pasted not all of the selector code. The problem has been solved, it was on the client. Client has a selector too, and a list of messages to send. After adding a message to the list, i Invoke selector.wakeup(), but it seems that if the messages are big, selector writes only the first one till the nest invocation.. – Luo May 03 '15 at 21:53
  • 1
    @Luo That is not a correct analysis. The selector doesn't write anything. The `write()` method is what does the writing. You thought you had written something and you hadn't. – user207421 May 04 '15 at 00:49