Ejemplo n.º 1
0
        private async Task RemoveParticipant(Participant participant, string?connectionId,
                                             CancellationToken cancellationToken)
        {
            _logger.LogDebug("RemoveParticipant() | {participant}, connectionId:{connectionId}", participant,
                             connectionId);

            if (connectionId == null)
            {
                if (!_connections.TryGetParticipant(participant.Id, out var connection))
                {
                    return;
                }

                connectionId = connection.ConnectionId;
            }

            if (_connections.TryRemoveParticipant(participant.Id,
                                                  new ParticipantConnection(participant.ConferenceId, connectionId)))
            {
                _logger.LogDebug("Remove participant connection");

                await _hubContext.Groups.RemoveFromGroupAsync(connectionId, CoreHubGroups.OfParticipant(participant),
                                                              cancellationToken);

                await _hubContext.Groups.RemoveFromGroupAsync(connectionId,
                                                              CoreHubGroups.OfConference(participant.ConferenceId), cancellationToken);

                if (await _repository.IsParticipantJoined(participant, connectionId))
                {
                    await using var @lock = await _repository.LockParticipantJoin(participant);

                    if (await _repository.IsParticipantJoined(participant, connectionId))
                    {
                        await _mediator.Publish(new ParticipantLeftNotification(participant, connectionId),
                                                @lock.HandleLostToken);
                    }
                }
                else
                {
                    _logger.LogDebug("Participant is not joined");
                }
            }
            else
            {
                _logger.LogDebug("Participant connection was already removed");
            }
        }
Ejemplo n.º 2
0
        public async Task <Unit> Handle(JoinConferenceRequest request, CancellationToken cancellationToken)
        {
            var(participant, connectionId, meta) = request;
            var(conferenceId, participantId)     = participant;

            _logger.LogDebug("Participant {participantId} is joining conference {conferenceId}", participantId,
                             conferenceId);

            var previousSession = await _joinedParticipantsRepository.AddParticipant(participant, connectionId);

            if (previousSession != null)
            {
                _logger.LogDebug("The participant {participantId} was already joined, kick existing connection.",
                                 participantId);
                await _mediator.Publish(new ParticipantKickedNotification(
                                            new Participant(previousSession.ConferenceId, participantId), previousSession.ConnectionId,
                                            ParticipantKickedReason.NewSessionConnected));
            }

            await using var @lock = await _joinedParticipantsRepository.LockParticipantJoin(participant);

            if (!await _joinedParticipantsRepository.IsParticipantJoined(participant, connectionId))
            {
                throw new ConcurrencyException("Race condition on participant join.");
            }

            _logger.LogDebug("Begin joining of participant {participant}", participant);

            // enable messaging just after kicking client
            await _mediator.Publish(new ParticipantInitializedNotification(participant));

            // do not merge these together as handlers for ParticipantJoinedNotification may want to send messages to the participant
            await _mediator.Send(new EnableParticipantMessagingRequest(participant, connectionId), cancellationToken);

            await _mediator.Publish(new ParticipantJoinedNotification(participant, meta));

            return(Unit.Value);
        }
Ejemplo n.º 3
0
        public async Task Handle(ParticipantKickedNotification notification, CancellationToken cancellationToken)
        {
            var(participant, connectionId, reason) = notification;

            var targetClient = connectionId != null
                ? _hubContext.Clients.Client(connectionId)
                : _hubContext.Clients.Group(CoreHubGroups.OfParticipant(participant));

            await targetClient.OnRequestDisconnect(new RequestDisconnectDto(reason), cancellationToken);

            if (connectionId != null)
            {
                // it's very important that we publish participant left, as a new participant may be joining right after this and
                // we have to clean up first
                await using (var @lock = await _repository.LockParticipantJoin(participant))
                {
                    await _mediator.Publish(new ParticipantLeftNotification(participant, connectionId),
                                            @lock.HandleLostToken);
                }
            }

            await _publishEndpoint.Publish <ParticipantKicked>(notification, cancellationToken);
        }