summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2023-02-01 11:18:49 +0100
committerGitHub <noreply@github.com>2023-02-01 11:18:49 +0100
commita6e9b6e9eef7e90c7158a248e1351575bf2e2369 (patch)
treec7c5306784ca72898aa1e3e2ee079a43d45978ef /lib
parentdfa6d28bc2311de99428547c1a6feaf831930111 (diff)
parenta46fa7eb8b709512a737b5dc341c3841aa3c0ff1 (diff)
Merge pull request #8477 from nextcloud/send-signaling-messages-when-starting-and-stopping-breakout-rooms
Send signaling messages when starting and stopping breakout rooms
Diffstat (limited to 'lib')
-rw-r--r--lib/Service/BreakoutRoomService.php4
-rw-r--r--lib/Signaling/BackendNotifier.php27
-rw-r--r--lib/Signaling/Listener.php85
-rw-r--r--lib/Signaling/Manager.php3
4 files changed, 116 insertions, 3 deletions
diff --git a/lib/Service/BreakoutRoomService.php b/lib/Service/BreakoutRoomService.php
index 9872ecdd4..e2180124a 100644
--- a/lib/Service/BreakoutRoomService.php
+++ b/lib/Service/BreakoutRoomService.php
@@ -432,6 +432,8 @@ class BreakoutRoomService {
throw new \InvalidArgumentException('mode');
}
+ $this->roomService->setBreakoutRoomStatus($parent, BreakoutRoom::STATUS_STOPPED);
+
$breakoutRooms = $this->manager->getMultipleRoomsByObject(BreakoutRoom::PARENT_OBJECT_TYPE, $parent->getToken());
foreach ($breakoutRooms as $breakoutRoom) {
$this->roomService->setLobby($breakoutRoom, Webinary::LOBBY_NON_MODERATORS, null);
@@ -441,8 +443,6 @@ class BreakoutRoomService {
}
}
- $this->roomService->setBreakoutRoomStatus($parent, BreakoutRoom::STATUS_STOPPED);
-
return $breakoutRooms;
}
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..a129f3b49 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,88 @@ 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;
+ }
+ }
+
+ if (!empty($sessionIds)) {
+ $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();
+ }
+ }
+
+ if (!empty($sessionIds)) {
+ $notifier->switchToRoom($breakoutRoom, $room->getToken(), $sessionIds);
+ }
+ }
+ }
+
public static function notifyParticipantsAfterNameUpdated(ModifyParticipantEvent $event): void {
if (self::isUsingInternalSignaling()) {
return;
diff --git a/lib/Signaling/Manager.php b/lib/Signaling/Manager.php
index 87f472900..8fb6667a1 100644
--- a/lib/Signaling/Manager.php
+++ b/lib/Signaling/Manager.php
@@ -55,7 +55,8 @@ class Manager {
$features = array_map('trim', $features);
return in_array('audio-video-permissions', $features, true)
&& in_array('incall-all', $features, true)
- && in_array('hello-v2', $features, true);
+ && in_array('hello-v2', $features, true)
+ && in_array('switchto', $features, true);
}
public function getSignalingServerLinkForConversation(?Room $room): string {