@ServiceRequestMapping(UPDATE_USER_ONLINE_STATUS_REQUEST)
    public ClientRequestHandler handleUpdateUserOnlineStatusRequest() {
        return clientRequest -> {
            UpdateUserOnlineStatusRequest request = clientRequest.turmsRequest()
                    .getUpdateUserOnlineStatusRequest();
            UserStatus userStatus = request.getUserStatus();
            if (userStatus == UserStatus.UNRECOGNIZED) {
                return Mono.just(RequestHandlerResult.of(ResponseStatusCode.ILLEGAL_ARGUMENT,
                        "The user status must not be UNRECOGNIZED"));
            }
            Mono<Boolean> updateMono;
            if (userStatus == UserStatus.OFFLINE) {
                updateMono = request.getDeviceTypesCount() > 0
                        ? sessionService.disconnect(clientRequest.userId(),
                                CollectionUtil.newSet(request.getDeviceTypesList()),
                                SessionCloseStatus.DISCONNECTED_BY_OTHER_DEVICE)
                        : sessionService.disconnect(clientRequest.userId(),
                                SessionCloseStatus.DISCONNECTED_BY_OTHER_DEVICE);
            } else {
                updateMono = userStatusService
                        .updateOnlineUserStatusIfPresent(clientRequest.userId(), userStatus);
            }
            boolean notifyMembers = notifyGroupMembersOfMemberOnlineStatusUpdated;
            boolean notifyNonBlockedRelatedUser =
                    notifyNonBlockedRelatedUsersOfUserOnlineStatusUpdated;
            if (!notifyMembers && !notifyNonBlockedRelatedUser) {
                return updateMono.thenReturn(RequestHandlerResult.of(
                        notifyRequesterOtherOnlineSessionsOfUserOnlineStatusUpdated,
                        clientRequest.turmsRequest()));
            }
            Mono<Set<Long>> queryMemberIds = notifyMembers
                    ? groupMemberService
                            .queryMemberIdsInUsersJoinedGroups(Set.of(clientRequest.userId()), true)
                    : PublisherPool.emptySet();
            Mono<List<Long>> queryRelatedUserIds;

            Recyclable<List<Long>> recyclableList;
            if (notifyNonBlockedRelatedUser) {
                recyclableList = ListRecycler.obtain();
                queryRelatedUserIds = userRelationshipService
                        .queryRelatedUserIds(Set.of(clientRequest.userId()), false)
                        .collect(Collectors.toCollection(recyclableList::getValue));
            } else {
                recyclableList = null;
                queryRelatedUserIds = PublisherPool.emptyList();
            }
            return queryMemberIds.zipWith(queryRelatedUserIds)
                    .map(results -> {
                        Set<Long> recipients = CollectionUtil.add(results.getT1(), results.getT2());
                        return RequestHandlerResult.of(
                                notifyRequesterOtherOnlineSessionsOfUserOnlineStatusUpdated,
                                recipients,
                                clientRequest.turmsRequest());
                    })
                    .doFinally(signalType -> {
                        if (recyclableList != null) {
                            recyclableList.recycle();
                        }
                    });
        };
    }
Do not notify the user status change to the related users and members of joined groups
because the client itself should query whether there are any user status changes, according
to their own business scenarios.
turms-service/src/main/java/im/turms/service/domain/user/access/servicerequest/controller/UserServiceController.java