code: public void disconnect(IConnection conn) {
          log.debug("Disconnect: {}", conn);
          // call disconnect handlers in reverse order of connection. ie. roomDisconnect is called before appDisconnect.
          final IClient client = conn.getClient();
          if (client == null) {
              // early bail out
              removeEventListener(conn);
              connectionStats.decrement();
              if (hasParent()) {
                  parent.disconnect(conn);
              }
              return;
          }
          // remove it if it exists
          if (clients.remove(client)) {
              IScopeHandler handler = getHandler();
              if (handler != null) {
                  try {
                      handler.disconnect(conn, this);
                  } catch (Exception e) {
                      log.error("Error while executing \"disconnect\" for connection {} on handler {}. {}", new Object[] { conn, handler, e });
                  }
                  try {
                      // there may be a timeout here ?
                      handler.leave(client, this);
                  } catch (Exception e) {
                      log.error("Error while executing \"leave\" for client {} on handler {}. {}", new Object[] { conn, handler, e });
                  }
              }
              // remove listener
              removeEventListener(conn);
              // decrement if there was a set of connections
              connectionStats.decrement();
              if (this.equals(conn.getScope())) {
                  final IServer server = getServer();
                  if (server instanceof Server) {
                      ((Server) server).notifyDisconnected(conn);
                  }
              }
          }
          if (hasParent()) {
              parent.disconnect(conn);
          }
      }
docs: Disconnect connection from scope
  
  @param conn Connection object