summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2022-12-19 01:43:01 +0100
committerDaniel Calviño Sánchez <danxuliu@gmail.com>2023-01-31 05:00:53 +0100
commit62fd48d1a764c24d731e24b9289917c6e2c9bdc8 (patch)
treec4410cfed51a464020372c51a9cbf80cb2ce0ec5 /lib
parentad21f0325288731f2eac3a45fc2c32b60bea6ed5 (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.php27
-rw-r--r--lib/Signaling/Listener.php81
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;