NIO Selector Thread, qui gère les canaux comme prévu, mais comment puis-je m’assurer que les canaux sont correctement fermés après utilisation?

J’ai donc le code suivant dans ma classe ServerRunnable:

public class FirmwareServerRunnable implements Runnable { private static Logger log = Logger.getLogger(FirmwareServerRunnable.class .getName()); private LinkedTransferQueue communicationQueue; private int serverPort = 48485; public FirmwareServerRunnable(int port, LinkedTransferQueue communicationQueue) { serverPort = port; this.communicationQueue = communicationQueue; } private boolean running; private ServerSocketChannel serverSocketChannel; @Override public void run() { try { Selector selector = Selector.open(); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(serverPort)); log.info("Selector Thread: FirmwareServer Runnable- Listening for connections on port: " + serverSocket.getLocalPort()); running = true; @SuppressWarnings("unused") SelectionKey serverAcceptKey = serverSocketChannel.register( selector, SelectionKey.OP_ACCEPT); while (running) { selector.select(); Set selectedKeys = selector.selectedKeys(); Iterator keyIterator = selectedKeys.iterator(); while (keyIterator.hasNext()) { SelectionKey key = (SelectionKey) keyIterator.next(); if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { acceptConnection(selector, key); keyIterator.remove(); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { CommunicationState commsState = (CommunicationState) key .attachment(); if (commsState.getCurrentState() == CommunicationState.STATE_READ) { readFromSocketChannel(key); keyIterator.remove(); } } else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { CommunicationState commsState = (CommunicationState) key .attachment(); if (commsState.getCurrentState() == CommunicationState.STATE_WRITE) { writeToSocketChannel(key); keyIterator.remove(); } } } } } catch (IOException e) { log.error( "Firmware Selector Thread: An IOException occurred", e); } } 

Ma méthode acceptConnection() accepte une connexion et y ajoute un object CommunicationState (une machine d’état) qui contient des éléments tels qu’un ByteBuffer , l’état actuel du canal, où le client se trouve actuellement dans le processus de communication, etc.
Ce serveur bascule entre les méthodes de communication en cours de processus. Initialement, il utilise des messages JSON pour communiquer avec le client, mais lorsqu’il arrive à un certain point, il commence à flasher le client avec un nouveau microprogramme à l’aide des commandes du protocole USART .

Une fois le processus terminé, le client se déconnecte et redémarre. Cela laisse mon canal dans un état inconnu. Je ne sais pas si la chaîne a été fermée ou pas de mon côté. Comment puis-je vérifier cela? Ai-je raison de penser que selector.selectedKeys() ne renvoie que les clés prêtes à être utilisées? Si c’est le cas, comment puis-je vérifier les connexions qui n’ont pas été correctement fermées? Puis-je le faire dans cette ServerRunnable while(running){} ?

Une option que j’ai envisagée est de joindre une référence à la clé elle-même à la machine CommunicationState, puis je peux obtenir une référence au canal une fois le processus terminé et le fermer. Mais je suis mal à l’aise avec cette solution pour une raison quelconque, cela ne me semble pas correct.

Si c’est le cas, même les clés de canal fermé sont incluses. key.isValid() je utiliser key.isValid() pour confirmer que la clé doit être supprimée définitivement?

J’apprécierais toutes les pensées que vous pourriez avoir sur le processus, je dois être quelque chose.

EDIT: un test rapide semble suggérer que les clés de canal ne sont pas incluses dans le jeu de touches sélectionné, sauf si elles sont prêtes pour l’une des trois opérations définies. Mon test était mauvais.

Une connexion qui a été fermée par le pair amènera le sélecteur à traiter votre canal comme étant lisible, et lorsque vous le lirez, vous obtiendrez -1, après quoi vous devrez fermer le canal, ce qui annulera sa clé de sélection.

MODIFIER

Si c’est le cas, même les clés de canal fermé sont incluses. Puis-je utiliser key.isValid () pour confirmer que la clé doit être supprimée définitivement?

Si vous fermez le canal, sa touche a été annulée, vous ne le verrez donc pas dans le jeu de touches sélectionné la prochaine fois. Si l’ homologue a fermé la connexion, voir ci-dessus.