diff options
author | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2022-12-19 01:43:01 +0100 |
---|---|---|
committer | Daniel Calviño Sánchez <danxuliu@gmail.com> | 2023-01-31 05:00:53 +0100 |
commit | 62fd48d1a764c24d731e24b9289917c6e2c9bdc8 (patch) | |
tree | c4410cfed51a464020372c51a9cbf80cb2ce0ec5 /lib | |
parent | ad21f0325288731f2eac3a45fc2c32b60bea6ed5 (diff) |
Send signaling message when starting or stopping breakout rooms
When the breakout room status changes a "switchto" message is sent to
all the active sessions in either the parent or the breakout rooms
(depending on whether they are being started or stopped) with the token
of the room that they have to switch to.
When the breakout rooms are started the message is sent only to non
moderators, as moderators do not have a single breakout room assigned.
On the other hand, when the breakout rooms are stopped the message is
also sent to all moderators (who are in a breakout room and not already
in the parent room), as all participants need to switch to the parent
room.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Signaling/BackendNotifier.php | 27 | ||||
-rw-r--r-- | lib/Signaling/Listener.php | 81 |
2 files changed, 108 insertions, 0 deletions
diff --git a/lib/Signaling/BackendNotifier.php b/lib/Signaling/BackendNotifier.php index 139107a9d..577cc7645 100644 --- a/lib/Signaling/BackendNotifier.php +++ b/lib/Signaling/BackendNotifier.php @@ -281,6 +281,33 @@ class BackendNotifier { } /** + * The given participants should switch to the given room. + * + * @param Room $room + * @param string $switchToRoomToken + * @param string[] $sessionIds + * @throws \Exception + */ + public function switchToRoom(Room $room, string $switchToRoomToken, array $sessionIds): void { + $start = microtime(true); + $this->backendRequest($room, [ + 'type' => 'switchto', + 'switchto' => [ + 'roomid' => $switchToRoomToken, + 'sessions' => $sessionIds, + ], + ]); + $duration = microtime(true) - $start; + $this->logger->debug('Switch to room: {token} {roomid} {sessions} ({duration})', [ + 'token' => $room->getToken(), + 'roomid' => $switchToRoomToken, + 'sessions' => print_r($sessionIds, true), + 'duration' => sprintf('%.2f', $duration), + 'app' => 'spreed-hpb', + ]); + } + + /** * The participant list of the given room has been modified. * * @param Room $room diff --git a/lib/Signaling/Listener.php b/lib/Signaling/Listener.php index 7087d49d9..2e11b9447 100644 --- a/lib/Signaling/Listener.php +++ b/lib/Signaling/Listener.php @@ -37,6 +37,8 @@ use OCA\Talk\Events\RemoveParticipantEvent; use OCA\Talk\Events\RemoveUserEvent; use OCA\Talk\Events\RoomEvent; use OCA\Talk\GuestManager; +use OCA\Talk\Manager; +use OCA\Talk\Model\BreakoutRoom; use OCA\Talk\Participant; use OCA\Talk\Room; use OCA\Talk\Service\ParticipantService; @@ -98,6 +100,7 @@ class Listener { $dispatcher->addListener(Room::EVENT_AFTER_END_CALL_FOR_EVERYONE, [self::class, 'sendEndCallForEveryone']); $dispatcher->addListener(Room::EVENT_AFTER_GUESTS_CLEAN, [self::class, 'notifyParticipantsAfterGuestClean']); $dispatcher->addListener(Room::EVENT_AFTER_SET_CALL_RECORDING, [self::class, 'sendSignalingMessageWhenToggleRecording']); + $dispatcher->addListener(Room::EVENT_AFTER_SET_BREAKOUT_ROOM_STATUS, [self::class, 'notifyParticipantsAfterSetBreakoutRoomStatus']); $dispatcher->addListener(GuestManager::EVENT_AFTER_NAME_UPDATE, [self::class, 'notifyParticipantsAfterNameUpdated']); $dispatcher->addListener(ChatManager::EVENT_AFTER_MESSAGE_SEND, [self::class, 'notifyUsersViaExternalSignalingToRefreshTheChat']); $dispatcher->addListener(ChatManager::EVENT_AFTER_SYSTEM_MESSAGE_SEND, [self::class, 'notifyUsersViaExternalSignalingToRefreshTheChat']); @@ -324,6 +327,84 @@ class Listener { $notifier->participantsModified($event->getRoom(), $sessionIds); } + public static function notifyParticipantsAfterSetBreakoutRoomStatus(RoomEvent $event): void { + if (self::isUsingInternalSignaling()) { + return; + } + + $room = $event->getRoom(); + if ($room->getBreakoutRoomStatus() === BreakoutRoom::STATUS_STARTED) { + self::notifyParticipantsAfterBreakoutRoomStarted($room); + } else { + self::notifyParticipantsAfterBreakoutRoomStopped($room); + } + } + + private static function notifyParticipantsAfterBreakoutRoomStarted(Room $room): void { + $manager = Server::get(Manager::class); + $breakoutRooms = $manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $room->getToken()); + + $switchToData = []; + + $participantService = Server::get(ParticipantService::class); + $parentRoomParticipants = $participantService->getSessionsAndParticipantsForRoom($room); + + $notifier = Server::get(BackendNotifier::class); + + foreach ($breakoutRooms as $breakoutRoom) { + $sessionIds = []; + + $breakoutRoomParticipants = $participantService->getParticipantsForRoom($breakoutRoom); + foreach ($breakoutRoomParticipants as $breakoutRoomParticipant) { + foreach (self::getSessionIdsForNonModeratorsMatchingParticipant($breakoutRoomParticipant, $parentRoomParticipants) as $sessionId) { + $sessionIds[] = $sessionId; + } + } + + $notifier->switchToRoom($room, $breakoutRoom->getToken(), $sessionIds); + } + } + + private static function getSessionIdsForNonModeratorsMatchingParticipant(Participant $targetParticipant, array $participants) { + $sessionIds = []; + + foreach ($participants as $participant) { + if ($participant->getAttendee()->getActorType() === $targetParticipant->getAttendee()->getActorType() && + $participant->getAttendee()->getActorId() === $targetParticipant->getAttendee()->getActorId() && + !$participant->hasModeratorPermissions()) { + $session = $participant->getSession(); + if ($session) { + $sessionIds[] = $session->getSessionId(); + } + } + } + + return $sessionIds; + } + + private static function notifyParticipantsAfterBreakoutRoomStopped(Room $room): void { + $manager = Server::get(Manager::class); + $breakoutRooms = $manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $room->getToken()); + + $participantService = Server::get(ParticipantService::class); + + $notifier = Server::get(BackendNotifier::class); + + foreach ($breakoutRooms as $breakoutRoom) { + $sessionIds = []; + + $participants = $participantService->getSessionsAndParticipantsForRoom($breakoutRoom); + foreach ($participants as $participant) { + $session = $participant->getSession(); + if ($session) { + $sessionIds[] = $session->getSessionId(); + } + } + + $notifier->switchToRoom($breakoutRoom, $room->getToken(), $sessionIds); + } + } + public static function notifyParticipantsAfterNameUpdated(ModifyParticipantEvent $event): void { if (self::isUsingInternalSignaling()) { return; |