private void onConnectionClosed(TurmsConnection connection, @Nullable Throwable throwable) {
        boolean isLocalNodeClient = connection.isLocalNodeClient();
        String nodeType = isLocalNodeClient
                ? "Client"
                : "Server";
        String nodeId = connection.getNodeId();
        Member member = nodeId == null
                ? null
                : discoveryService.getMember(nodeId);
        String memberIdAndAddress = member == null
                ? ""
                : " "
                        + getMemberIdAndAddress(nodeId, member);
        boolean closing = connection.isClosing();
        LogLevel logLevel = closing
                ? LogLevel.INFO
                : LogLevel.WARN;
        if (member == null) {
            LOGGER.log(logLevel,
                    "[{}] The connection to an unknown member has been closed{}",
                    nodeType,
                    closing
                            ? ""
                            : " unexpectedly",
                    throwable);
        } else {
            connectingMembers.remove(nodeId);
            LOGGER.log(logLevel,
                    "[{}] The connection to the member{} has been closed{}",
                    nodeType,
                    memberIdAndAddress,
                    closing
                            ? ""
                            : " unexpectedly",
                    throwable);
        }
        for (MemberConnectionListener listener : connection.getListeners()) {
            try {
                listener.onConnectionClosed();
            } catch (Exception e) {
                LOGGER.error("Caught an error while notifying the onConnectionClosed listener: "
                        + listener.getClass()
                                .getName(),
                        e);
            }
        }
        boolean isKnownMember = nodeId != null && discoveryService.isKnownMember(nodeId);
        boolean isClosing = discoveryService.getLocalNodeStatusManager()
                .isClosing();
        if (isLocalNodeClient && isKnownMember && !isClosing) {
            LOGGER.info("[{}] Try to reconnect the member{} after {} millis",
                    nodeType,
                    memberIdAndAddress,
                    reconnectInterval.toMillis());
            Mono.delay(reconnectInterval)
                    .subscribe(null, null, () -> {
                        Member memberToConnect = discoveryService.getAllKnownMembers()
                                .get(nodeId);
                        if (memberToConnect == null) {
                            LOGGER.info(
                                    "[{}] Stop to reconnect the member{} because it has been unregistered",
                                    nodeType,
                                    memberIdAndAddress);
                        } else {
                            connectMemberUntilSucceedOrRemoved(memberToConnect);
                        }
                    });
        } else {
            String reason = isLocalNodeClient
                    ? isKnownMember
                            ? "the local node is closing"
                            : "the member is unknown"
                    : "the local node is server";
            LOGGER.info("[{}] Stop to connect the member{} because {}",
                    nodeType,
                    memberIdAndAddress,
                    reason);
        }
    }
@param member is null when accepting a connection on the server side
turms-server-common/src/main/java/im/turms/server/common/infra/cluster/service/connection/ConnectionService.java