code: @Override
      public final void close() {
          preDisconnectListeners.forEach(Runnable::run);
  
          flush();
  
          while (writing.get()) {
              Thread.onSpinWait();
          }
  
          Channeled.super.close();
  
          if (executor != null) {
              executor.shutdownNow();
          }
  
          while (channel.isOpen()) {
              Thread.onSpinWait();
          }
  
          if (server != null) {
              server.connectedClients.remove(this);
          }
          
          postDisconnectListeners.forEach(Runnable::run);
      }
docs: Closes this {@link Client}'s backing {@link AsynchronousSocketChannel} after flushing any queued packets.
  <br><br>
  Any registered pre-disconnect listeners are fired before remaining packets are flushed, and registered
  post-disconnect listeners are fired after the backing channel has closed successfully.
  <br><br>
  Listeners are fired in the same order that they were registered in.