3 Replies Latest reply: Jul 27, 2010 5:48 AM by EJP RSS

    nio - how to check if channel are still active

    843790
      Hi,
      I've got a server / client application using nio library that already works, but there still seems to be one exception to catch.

      A client connects to the server and keeps the connection alive. Every 3 seconds it sends data to the server to say "Hello, I m still here" and to update a session saved in a server side database. Then the server sends back data to inform the client about the database status. The server checks the time of each session. If the time of a session is older than 60 seconds it closes the session in the database. That means that each client has 60 seconds time for updating a session. But sometimes the server doesn't get any data on a socketchannel any more when e.g. the client couldn't shutdown the socketchannel cleanly (bad wireless lan quality, or the client user just powers of the pc). In this case the server still checks for a readable state on that socketchannel:
            while(true) {
              int n = selector.select();
      
              if(0 == n) {
                continue;
              }
      
              Set<SelectionKey> readyKeys = selector.selectedKeys();
              Iterator<SelectionKey> iterator = readyKeys.iterator();
        
              while (iterator.hasNext()) {
                SelectionKey selKey = iterator.next();
                iterator.remove();
                
                if(!selKey.isValid()) {
                  continue;
                }
                
                if (selKey.isAcceptable()) {
                  //handle new connection
                } 
      
                if (selKey.isReadable()) {
                  processSocketChannel(selKey);
                }
      How can I check if the socketchannel is still open when I never get a readable state?

      Thomas B
        • 1. Re: nio - how to check if channel are still active
          EJP
          Implement a timeout at the server side. Keep track of the time of the last real activity of each channel, and when it gets too long close e channel. You can do that at the bottom of the select loop, processing channels which weren't selected.
          • 2. Re: nio - how to check if channel are still active
            843790
            Hi, do you think calling key.channel().close(); and key.cancel(); in the method checkChannelSessions() would be good enough?
                    while (iterator.hasNext()) {
                      SelectionKey selKey = iterator.next();
                      iterator.remove();
                      
                      if(!selKey.isValid()) {
                        continue;
                      }
                      
                      
                      if (selKey.isAcceptable()) {
                        //handle new connection
                        addChannelSession(selKey);
                      } 
            
                      if (selKey.isReadable()) {
                        processSocketChannel(selKey);
                        updateChannelSession(selKey);
                      }
                    }
                    
                    checkChannelSessions();
                  }
              private void checkChannelSessions() {
               Iterator<Map.Entry<SelectionKey, Long>> it = selectionkey_map.entrySet().iterator();
            
               while (it.hasNext()) {
                 Map.Entry<SelectionKey, Long> entry = it.next();
                 
                 SelectionKey key = entry.getKey();
                 Long millis      = entry.getValue();
                 
                 if(System.currentTimeMillis() - millis > 6000) {
                   try {
                     key.channel().close();
                     key.cancel();
             
                   } catch (IOException e) {
                     
                   }   
                  }
                }
              }
            • 3. Re: nio - how to check if channel are still active
              EJP
              Close is enough, it does the cancel for you.