示例#1
0
        public async Task AddParticipant_ParticipantDoesNotExist_CreateParticipantAndReturnNull()
        {
            const string participantId = "9103f4d781064c478028c8e26d5c02c0";
            const string conferenceId  = "d57e6f6be5024c47ad3901c038d208a1";
            const string connectionId  = "4f34017716144873b195624f20a647f7";

            var participantKey = $"{participantId}:ParticipantToConference";
            var conferenceKey  = $"{conferenceId}:ConferenceParticipants";

            // arrange
            await _database.KeyDeleteAsync(participantKey);

            await _database.KeyDeleteAsync(conferenceKey);

            // act
            var result = await _repository.AddParticipant(new Participant(conferenceId, participantId), connectionId);

            // assert
            Assert.Null(result);

            string?actualConferenceId = await _database.StringGetAsync(participantKey);

            Assert.Equal(conferenceId, actualConferenceId);

            string?actualConnectionId = await _database.HashGetAsync(conferenceKey, participantId);

            Assert.Equal(connectionId, actualConnectionId);
        }
        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);
        }