code: @Override
      public void processClose(WebSocketChannel channel, int code, String reason) {
          LOG.entering(CLASS_NAME, "close");
  
          //2. check current readyState
          WebSocketCompositeChannel parent = (WebSocketCompositeChannel)channel;
  
          // When the connection timeout expires due to network loss, we first
          // invoke doClose() to inform the application immediately. Then, we
          // invoke processClose() to close the connection but it may take a
          // while to return. When doClose() is invoked, readyState is set to
          // CLOSED. However, we do want processClose() to be invoked all the
          // all the way down to close the connection. That's why we are no
          // longer throwing an exception here if readyState is CLOSED.
          
          if (!parent.closing) {
              parent.closing = true;
              parent.readyState = ReadyState.CLOSING;
              
              try {
                  WebSocketSelectedChannel selectedChannel = parent.selectedChannel;
                  selectedChannel.handler.processClose(selectedChannel, code, reason);                
              }
              catch (Exception e) {
                  doClose(parent, false, CloseCommandMessage.CLOSE_ABNORMAL, e.getMessage());
              }
          }
      }
docs: Disconnect the WebSocket
  
  @throws Exception
  if the disconnect does not succeed