INTEGRITY Документация

Сессионные залы

Сессионные залы позволяют участникам встречи разделиться на небольшие группы для целевых обсуждений и совместной работы. С распространением удалённой работы и онлайн-обучения сессионные залы стали незаменимым инструментом для повышения вовлечённости и укрепления сообщества в виртуальной среде. Это оптимальный выбор для воркшопов, онлайн-занятий или случаев, когда нужно поговорить наедине с отдельными участниками за пределами основной встречи.

В RealtimeKit breakout-комнаты создаются как отдельные встречи. Каждая breakout-комната представляет собой независимую встречу, которой можно управлять как любой другой встречей RealtimeKit. RealtimeKit предоставляет набор SDK API для создания и управления breakout-комнатами, а также для переключения между ними.

Ключевые функции

Ниже перечислены некоторые ключевые возможности сессионных залов RealtimeKit:

Роли в сессионном зале

Роли в сессионном зале управляются пресетами.

Host

Организаторы могут создавать сессионные залы, назначать в них участников, открывать и закрывать сессионные залы, а также переключаться между ними.

Участники

Как участник сессионного зала, вы можете:

Аудио и видео

Каждый сессионный зал функционирует как отдельная встреча. При переключении в сессионный зал из основной встречи аудио и видео автоматически переключаются на сессионную встречу. Вы можете включать и отключать звук, а также запускать и останавливать видео в любой момент сессионной встречи, точно так же, как и в основной встрече.

Когда встреча в сессионном зале завершается, ваши аудио и видео автоматически переключаются обратно на основную встречу.

Запись сессионных встреч

Каждая сессионная встреча представляет собой отдельную сессию. Запись каждой сессионной встречи хранится и управляется отдельно, как и для любой другой встречи RealtimeKit. Подробнее см. Запись.

Управление сессионными залами

Сессионные залы позволяют участникам разделиться на отдельные сессии. Организатор может создавать сессионные залы, распределять по ним участников, а также открывать и закрывать их.

Создание пресетов

Пресет представляет собой набор разрешений и настроек интерфейса, которые применяются к организаторам и участникам. Он определяет внешний вид, ощущения от использования и поведение сессионного зала.

Для сессионных залов необходимо предоставить организаторам и участникам следующие разрешения в Connected Meetings:

Host

Пресет организатора должен иметь Полный доступ разрешение в Connected Meetings. Это позволяет организатору:

Участники

Участникам можно предоставить следующие разрешения:

Сохраните пресет

  1. После того как вы внесли все изменения в пресет, нажмите Save
  2. Введите имя пресета и нажмите Save
  3. Ваш пресет отображается в списке. Нажмите Изменить чтобы внести какие-либо изменения

Создание встречи

Создание встречи RealtimeKit с использованием API создания встречи. Этот API возвращает уникальный идентификатор вашей встречи.

Добавьте участников

После создания встречи добавьте каждого участника с помощью API добавления участника. presetName созданный ранее, необходимо передать в теле запроса Add Participant API.

Проверяйте разрешения

Прежде чем создавать сессионные залы, проверьте разрешения текущего участника и убедитесь, что у него есть необходимые разрешения для создания сессионных залов. Неверные разрешения могут привести к возникновению ошибок.

// Check if breakout rooms are supported
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;

// Check if any breakout rooms are already created
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;

// Check if the current participant has permission to create breakout rooms
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;

// Check if the current participant has permission to switch to parent meeting
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;

// Check if the current participant has permission to switch to connected meeting
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;
// Check if breakout rooms are supported
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;

// Check if any breakout rooms are already created
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;

// Check if the current participant has permission to create breakout rooms
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;

// Check if the current participant has permission to switch to parent meeting
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;

// Check if the current participant has permission to switch to connected meeting
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;
// Check if breakout rooms are supported
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;

// Check if any breakout rooms are already created
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;

// Check if the current participant has permission to create breakout rooms
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;

// Check if the current participant has permission to switch to parent meeting
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;

// Check if the current participant has permission to switch to connected meeting
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;
val connectedMeetings = meeting.connectedMeetings

// Check if breakout rooms are active
val areBreakoutRoomsActive = connectedMeetings.isActive

// Check permissions on the local participant
val permissions = meeting.self.permissions.connectedMeetings

// Check if the current participant has permission to create/alter breakout rooms
val hasPermissionToAlterBreakoutRooms = permissions.canAlterConnectedMeetings

// Check if the current participant has permission to switch between breakout rooms
val hasPermissionToSwitchConnectedMeetings = permissions.canSwitchConnectedMeetings

// Check if the current participant has permission to switch back to the parent meeting
val hasPermissionToSwitchToParentMeeting = permissions.canSwitchToParentMeeting
let connectedMeetings = meeting.connectedMeetings

// Check if breakout rooms are active
let areBreakoutRoomsActive = connectedMeetings.isActive

// Check permissions on the local participant
let permissions = meeting.self.permissions.connectedMeetings

// Check if the current participant has permission to create/alter breakout rooms
let hasPermissionToAlterBreakoutRooms = permissions.canAlterConnectedMeetings

// Check if the current participant has permission to switch between breakout rooms
let hasPermissionToSwitchConnectedMeetings = permissions.canSwitchConnectedMeetings

// Check if the current participant has permission to switch back to the parent meeting
let hasPermissionToSwitchToParentMeeting = permissions.canSwitchToParentMeeting
const [meeting] = useRealtimeKitClient();

// Check if any breakout rooms are currently active
const areBreakoutRoomsActive = meeting?.connectedMeetings.isActive;

// Check whether the local participant can create, rename, or delete rooms and move any participant
const canAlterBreakoutRooms = meeting?.self.permissions.connectedMeetings.canAlterConnectedMeetings;

// Check whether the local participant can move themselves to any breakout room
const canSwitchRooms = meeting?.self.permissions.connectedMeetings.canSwitchConnectedMeetings;

// Check whether the local participant can return to the parent meeting
const canReturnToParent = meeting?.self.permissions.connectedMeetings.canSwitchToParentMeeting;

Создание сессионных залов

const breakoutRooms = await meeting.connectedMeetings.createMeetings([
  { title: "Breakout Room 1" },
  { title: "Breakout Room 2" },
  { title: "Breakout Room 3" },
]);

console.log("Created Breakout Rooms: ", breakoutRooms.map((room) => "Id:: " + room.id + " --- Title:: " + room.title).join("\n"));

breakoutRooms представляет собой массив базовой информации о встрече, такой как id и title. Вы можете использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

const breakoutRooms = await meeting.connectedMeetings.createMeetings([
  { title: "Breakout Room 1" },
  { title: "Breakout Room 2" },
  { title: "Breakout Room 3" },
]);

console.log("Created Breakout Rooms: ", breakoutRooms.map((room) => "Id:: " + room.id + " --- Title:: " + room.title).join("\n"));

breakoutRooms представляет собой массив базовой информации о встрече, такой как id и title. Вы можете использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

const breakoutRooms = await meeting.connectedMeetings.createMeetings([
  { title: "Breakout Room 1" },
  { title: "Breakout Room 2" },
  { title: "Breakout Room 3" },
]);

console.log("Created Breakout Rooms: ", breakoutRooms.map((room) => "Id:: " + room.id + " --- Title:: " + room.title).join("\n"));

breakoutRooms представляет собой массив базовой информации о встрече, такой как id и title. Вы можете использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

meeting.connectedMeetings.createMeetings(
    titles = listOf("Breakout Room 1", "Breakout Room 2", "Breakout Room 3")
) { result ->
    result.onSuccess { breakoutRooms ->
        val roomInfo = breakoutRooms.joinToString("\n") { "Id:: ${it.id} --- Title:: ${it.title}" }
        println("Created Breakout Rooms: $roomInfo")
    }.onFailure { error ->
        println("Failed to create breakout rooms: ${error.value.message}")
    }
}

breakoutRooms представляет собой список основной информации о встрече, такой как id и title. Можно использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

meeting.connectedMeetings.createMeetings(titles: ["Breakout Room 1", "Breakout Room 2", "Breakout Room 3"]) { result in
    switch result {
    case .success(let breakoutRooms):
        let roomInfo = breakoutRooms.map { "Id:: \($0.id) --- Title:: \($0.title)" }.joined(separator: "\n")
        print("Created Breakout Rooms: \(roomInfo)")
    case .failure(let error):
        print("Failed to create breakout rooms: \(error.value.message)")
    }
}

breakoutRooms представляет собой массив основной информации о встрече, такой как id и title. Можно использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

const breakoutRooms = await meeting.connectedMeetings.createMeetings([
  { title: "Breakout Room 1" },
  { title: "Breakout Room 2" },
  { title: "Breakout Room 3" },
]);

console.log("Created Breakout Rooms: ", breakoutRooms.map((room) => "Id:: " + room.id + " --- Title:: " + room.title).join("\n"));

breakoutRooms представляет собой массив базовой информации о встрече, такой как id и title. Вы можете использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

Получение списка сессионных залов и их участников

Если в комнате несколько организаторов создают сессионные залы, вы можете получить сводный список сессионных залов с помощью следующего API.

const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

breakoutRoomsInfo представляет собой объект, содержащий список сессионных залов и их участников, а также сведения о родительской встрече.

Эти данные можно использовать для отображения списка сессионных залов и участников в интерфейсе. Этот API заново запрашивает список сессионных залов и участников, поэтому его можно считать источником достоверных данных о сессионных залах и участниках. Рекомендуется вызывать этот API, чтобы получать актуальный список сессионных залов и участников, если происходит много изменений.

Также можно прослушивать stateUpdate событие, чтобы получать актуальный список сессионных залов и участников по мере их обновления в реальном времени.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});

  // Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
  console.log("Meetings List", meeting.connectedMeetings.meetings);
  console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
});
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

breakoutRoomsInfo представляет собой объект, содержащий список сессионных залов и их участников, а также сведения о родительской встрече.

Эти данные можно использовать для отображения списка сессионных залов и участников в интерфейсе. Этот API заново запрашивает список сессионных залов и участников, поэтому его можно считать источником достоверных данных о сессионных залах и участниках. Рекомендуется вызывать этот API, чтобы получать актуальный список сессионных залов и участников, если происходит много изменений.

Также можно прослушивать stateUpdate событие, чтобы получать актуальный список сессионных залов и участников по мере их обновления в реальном времени.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});

  // Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
  console.log("Meetings List", meeting.connectedMeetings.meetings);
  console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
});
const breakoutRooms = await meeting.connectedMeetings.createMeetings([
  { title: "Breakout Room 1" },
  { title: "Breakout Room 2" },
  { title: "Breakout Room 3" },
]);

console.log("Created Breakout Rooms: ", breakoutRooms.map((room) => "Id:: " + room.id + " --- Title:: " + room.title).join("\n"));

breakoutRooms представляет собой массив базовой информации о встрече, такой как id и title. Вы можете использовать id этих объектов, чтобы переместить участников в дополнительную комнату.

meeting.connectedMeetings.getConnectedMeetings { result ->
    result.onSuccess { breakoutRoomsInfo ->
        println("Parent Meeting: ${breakoutRoomsInfo.parentMeeting}")
        println("Breakout Rooms: ${breakoutRoomsInfo.meetings}")
    }.onFailure { error ->
        println("Failed to fetch breakout rooms: ${error.value.message}")
    }
}

breakoutRoomsInfo представляет собой объект, содержащий список сессионных залов и их участников, а также сведения о родительской встрече.

Эти данные можно использовать для отображения списка сессионных залов и участников в интерфейсе. Этот API заново запрашивает список сессионных залов и участников, поэтому его можно считать источником достоверных данных. Рекомендуется вызывать этот API, чтобы получать актуальное состояние, если происходит много изменений.

Также можно прослушивать onStateUpdate событие, чтобы получать обновления списка сессионных залов и участников в реальном времени.

meeting.addConnectedMeetingsEventListener(object : RtkConnectedMeetingsEventListener {
    override fun onStateUpdate(meetings: List<RtkConnectedMeeting>, parentMeeting: RtkConnectedMeeting?) {
        println("State updated. Meetings: $meetings, Parent: $parentMeeting")

        // Alternatively, access state directly from the connectedMeetings object
        println("Meetings List: ${meeting.connectedMeetings.meetings}")
        println("Parent Meeting: ${meeting.connectedMeetings.parentMeeting}")
    }

    override fun onChangingMeeting(meetingId: String) {}
    override fun onMeetingChanged(error: MeetingError?) {}
})
meeting.connectedMeetings.getConnectedMeetings { result in
    switch result {
    case .success(let breakoutRoomsInfo):
        print("Parent Meeting: \(String(describing: breakoutRoomsInfo.parentMeeting))")
        print("Breakout Rooms: \(breakoutRoomsInfo.meetings)")
    case .failure(let error):
        print("Failed to fetch breakout rooms: \(error.value.message)")
    }
}

breakoutRoomsInfo представляет собой объект, содержащий список сессионных залов и их участников, а также сведения о родительской встрече.

Эти данные можно использовать для отображения списка сессионных залов и участников в интерфейсе. Этот API заново запрашивает список сессионных залов и участников, поэтому его можно считать источником достоверных данных. Рекомендуется вызывать этот API, чтобы получать актуальное состояние, если происходит много изменений.

Также можно прослушивать onStateUpdate событие, чтобы получать обновления списка сессионных залов и участников в реальном времени.

class MyListener: RtkConnectedMeetingsEventListener {
    func onStateUpdate(meetings: [RtkConnectedMeeting], parentMeeting: RtkConnectedMeeting?) {
        print("State updated. Meetings: \(meetings), Parent: \(String(describing: parentMeeting))")

        // Alternatively, access state directly from the connectedMeetings object
        print("Meetings List: \(meeting.connectedMeetings.meetings)")
        print("Parent Meeting: \(String(describing: meeting.connectedMeetings.parentMeeting))")
    }

    func onChangingMeeting(meetingId: String) {}
    func onMeetingChanged(error: MeetingError?) {}
}

meeting.addConnectedMeetingsEventListener(MyListener())
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

breakoutRoomsInfo представляет собой объект, содержащий список сессионных залов и их участников, а также сведения о родительской встрече.

Эти данные можно использовать для отображения списка сессионных залов и участников в интерфейсе. Этот API заново запрашивает список сессионных залов и участников, поэтому его можно считать источником достоверных данных о сессионных залах и участниках. Рекомендуется вызывать этот API, чтобы получать актуальный список сессионных залов и участников, если происходит много изменений.

Также можно прослушивать stateUpdate событие, чтобы получать актуальный список сессионных залов и участников по мере их обновления в реальном времени.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});

  // Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
  console.log("Meetings List", meeting.connectedMeetings.meetings);
  console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
});

Перемещение участников в сессионные залы

После создания breakout-комнат распределите по ним участников.

// Retrieve list of breakout rooms & participants
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

/*
* You can retrieve meetingIds and participantIds from the breakoutRoomsInfo object.
* Based on where the participant currently is, you can decide the sourceMeetingId and targetMeetingId.
*/

// Move participants to breakout rooms
const response = await meeting.connectedMeetings.moveParticipants(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  ["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds, array of participant ids to be moved
);
// Retrieve list of breakout rooms & participants
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

/*
* You can retrieve meetingIds and participantIds from the breakoutRoomsInfo object.
* Based on where the participant currently is, you can decide the sourceMeetingId and targetMeetingId.
*/

// Move participants to breakout rooms
const response = await meeting.connectedMeetings.moveParticipants(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  ["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds, array of participant ids to be moved
);
// Retrieve list of breakout rooms & participants
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

/*
* You can retrieve meetingIds and participantIds from the breakoutRoomsInfo object.
* Based on where the participant currently is, you can decide the sourceMeetingId and targetMeetingId.
*/

// Move participants to breakout rooms
const response = await meeting.connectedMeetings.moveParticipants(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  ["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds, array of participant ids to be moved
);
// Retrieve list of breakout rooms & participants
meeting.connectedMeetings.getConnectedMeetings { result ->
    result.onSuccess { breakoutRoomsInfo ->
        /*
         * You can retrieve meetingIds and participantIds from breakoutRoomsInfo.
         * Based on where the participant currently is, decide the sourceMeetingId and targetMeetingId.
         */

        // Move participants to a breakout room
        meeting.connectedMeetings.moveParticipants(
            sourceMeetingId = "SOURCE_MEETING_ID",
            destinationMeetingId = "TARGET_MEETING_ID",
            participantIds = listOf("PARTICIPANT_ID_1", "PARTICIPANT_ID_2")
        ) { error ->
            if (error != null) {
                println("Failed to move participants: $error")
            } else {
                println("Participants moved successfully")
            }
        }
    }
}
// Retrieve list of breakout rooms & participants
meeting.connectedMeetings.getConnectedMeetings { result in
    switch result {
    case .success(let breakoutRoomsInfo):
        /*
         * You can retrieve meetingIds and participantIds from breakoutRoomsInfo.
         * Based on where the participant currently is, decide the fromMeetingId and toMeetingId.
         */

        // Move participants to a breakout room
        meeting.connectedMeetings.moveParticipants(
            sourceMeetingId: "SOURCE_MEETING_ID",
            destinationMeetingId: "TARGET_MEETING_ID",
            participantIds: ["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"]
        ) { error in
            if let error = error {
                print("Failed to move participants: \(error)")
            } else {
                print("Participants moved successfully")
            }
        }
    case .failure(let error):
        print("Failed to fetch breakout rooms: \(error.value.message)")
    }
}
// Retrieve list of breakout rooms & participants
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();

/*
* You can retrieve meetingIds and participantIds from the breakoutRoomsInfo object.
* Based on where the participant currently is, you can decide the sourceMeetingId and targetMeetingId.
*/

// Move participants to breakout rooms
const response = await meeting.connectedMeetings.moveParticipants(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  ["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds, array of participant ids to be moved
);

Перемещение участников с определённым пресетом в сессионные залы

После создания breakout-комнат распределите по ним участников.

const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  [{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // array of objects with presetId field
);
const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  [{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // array of objects with presetId field
);
const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  [{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // array of objects with presetId field
);
meeting.connectedMeetings.moveParticipantsWithCustomPreset(
    sourceMeetingId = "SOURCE_MEETING_ID",
    destinationMeetingId = "TARGET_MEETING_ID",
    participants = listOf(
        MoveParticipantPayload(id = "PARTICIPANT_ID_1", presetId = "PRESET_ID_1"),
        MoveParticipantPayload(id = "PARTICIPANT_ID_2", presetId = "PRESET_ID_2")
    )
) { error ->
    if (error != null) {
        println("Failed to move participants: $error")
    } else {
        println("Participants moved with custom preset successfully")
    }
}
meeting.connectedMeetings.moveParticipantsWithCustomPreset(
    sourceMeetingId: "SOURCE_MEETING_ID",
    destinationMeetingId: "TARGET_MEETING_ID",
    participants: [
        MoveParticipantPayload(id: "PARTICIPANT_ID_1", presetId: "PRESET_ID_1"),
        MoveParticipantPayload(id: "PARTICIPANT_ID_2", presetId: "PRESET_ID_2")
    ]
) { error in
    if let error = error {
        print("Failed to move participants: \(error)")
    } else {
        print("Participants moved with custom preset successfully")
    }
}
const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
  "SOURCE_MEETING_ID", // sourceMeetingId, meeting id where participants are currently in
  "TARGET_MEETING_ID", // targetMeetingId, meeting id where participants are to be moved
  [{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // array of objects with presetId field
);

Перемещение локального участника в сессионный зал

Чтобы переместить локального участника в другой сессионный зал или обратно в родительскую встречу, используйте тот же API, что и для перемещения других участников, но передайте ID локального участника. У локального участника должны быть необходимые разрешения: canSwitchConnectedMeetings чтобы переключаться между сессионными залами, или canSwitchToParentMeeting чтобы вернуться в родительскую встречу, если запрос был инициирован локальным участником, не являющимся хостом.

Обработка событий breakout-комнат

Если участник был перемещён в сессионный зал, changingMeeting событие срабатывает, после чего следует meetingChanged событие. Эти события также срабатывают, когда участник переключается между основной встречей и сессионными залами. Если участнику назначен сессионный зал, он присоединится к нему автоматически, и вызывать присоединение к встрече вручную не потребуется.

// Listen to changingMeeting event to show a custom UI to indicate that a meeting switch is happening
meeting.connectedMeetings.on("changingMeeting", (meetingId) => {
	console.log("Switching to breakout room or main meeting with id: " + meetingId);
	console.log("Show a Custom UI to indicate that a meeting switch is happening");
});

// Listen to meetingChanged event to update the meeting object reference
meeting.connectedMeetings.on("meetingChanged", (newMeeting) => {
	console.log("Switched to breakout room or main meeting");
	console.log("Every action now should be performed on this meeting");
});
// Listen to changingMeeting event to show a custom UI to indicate that a meeting switch is happening
meeting.connectedMeetings.on("changingMeeting", (meetingId) => {
	console.log("Switching to breakout room or main meeting with id: " + meetingId);
	console.log("Show a Custom UI to indicate that a meeting switch is happening");
});

// Listen to meetingChanged event to update the meeting object reference
meeting.connectedMeetings.on("meetingChanged", (newMeeting) => {
	console.log("Switched to breakout room or main meeting");
	console.log("Every action now should be performed on this meeting");
});
// Listen to changingMeeting event to show a custom UI to indicate that a meeting switch is happening
meeting.connectedMeetings.on("changingMeeting", (meetingId) => {
	console.log("Switching to breakout room or main meeting with id: " + meetingId);
	console.log("Show a Custom UI to indicate that a meeting switch is happening");
});

// Listen to meetingChanged event to update the meeting object reference
meeting.connectedMeetings.on("meetingChanged", (newMeeting) => {
	console.log("Switched to breakout room or main meeting");
	console.log("Every action now should be performed on this meeting");
});
meeting.addConnectedMeetingsEventListener(object : RtkConnectedMeetingsEventListener {
    // Triggered when a meeting switch is initiated — use this to show a loading UI
    override fun onChangingMeeting(meetingId: String) {
        println("Switching to breakout room or main meeting with id: $meetingId")
        println("Show a custom UI to indicate that a meeting switch is happening")
    }

    // Triggered when the meeting switch is complete
    override fun onMeetingChanged(error: MeetingError?) {
        if (error != null) {
            println("Failed to switch meeting: $error")
        } else {
            println("Switched to breakout room or main meeting successfully")
        }
    }

    override fun onStateUpdate(meetings: List<RtkConnectedMeeting>, parentMeeting: RtkConnectedMeeting?) {}
})
class MyListener: RtkConnectedMeetingsEventListener {
    // Triggered when a meeting switch is initiated — use this to show a loading UI
    func onChangingMeeting(meetingId: String) {
        print("Switching to breakout room or main meeting with id: \(meetingId)")
        print("Show a custom UI to indicate that a meeting switch is happening")
    }

    // Triggered when the meeting switch is complete
    func onMeetingChanged(error: MeetingError?) {
        if let error = error {
            print("Failed to switch meeting: \(error)")
        } else {
            print("Switched to breakout room or main meeting successfully")
        }
    }

    func onStateUpdate(meetings: [RtkConnectedMeeting], parentMeeting: RtkConnectedMeeting?) {}
}

meeting.addConnectedMeetingsEventListener(MyListener())

useRealtimeKitClient хук автоматически обрабатывает meetingChanged событие и меняет активную ссылку на клиент при перемещении локального участника в сессионный зал или обратно на основную встречу. Дополнительная настройка не требуется.

Если вы используете RtkMeeting компонента UI Kit переходный интерфейс (экран «Joining…») также обрабатывается автоматически.

Чтобы показать собственный экран загрузки во время переключения, прослушивайте changingMeeting событие:

useEffect(() => {
  if (!meeting) return;

  const onChangingMeeting = (meetingId: string) => {
    console.log("Switching to meeting:", meetingId);
    // Show a loading indicator
  };

  meeting.connectedMeetings.on("changingMeeting", onChangingMeeting);
  return () => meeting.connectedMeetings.removeListener("changingMeeting", onChangingMeeting);
}, [meeting]);

Закройте сессионные залы

Сессионные залы можно закрыть или удалить. Это заставит участников этих встреч перейти в главную комнату.

await meeting.connectedMeetings.deleteMeetings([
  "MEETING_ID_TO_CLOSE_1",
  "MEETING_ID_TO_CLOSE_2",
]);

Это также вызвало бы stateUpdate событие, обновляющее список сессионных залов и участников.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});
});

// Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
await meeting.connectedMeetings.deleteMeetings([
  "MEETING_ID_TO_CLOSE_1",
  "MEETING_ID_TO_CLOSE_2",
]);

Это также вызвало бы stateUpdate событие, обновляющее список сессионных залов и участников.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});
});

// Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
await meeting.connectedMeetings.deleteMeetings([
  "MEETING_ID_TO_CLOSE_1",
  "MEETING_ID_TO_CLOSE_2",
]);

Это также вызвало бы stateUpdate событие, обновляющее список сессионных залов и участников.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});
});

// Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
meeting.connectedMeetings.deleteMeetings(
    meetingIds = listOf("MEETING_ID_TO_CLOSE_1", "MEETING_ID_TO_CLOSE_2")
) { error ->
    if (error != null) {
        println("Failed to close breakout rooms: $error")
    } else {
        println("Breakout rooms closed successfully")
    }
}

Это также вызовет onStateUpdate событие, обновляющее список сессионных залов и участников.

meeting.addConnectedMeetingsEventListener(object : RtkConnectedMeetingsEventListener {
    override fun onStateUpdate(meetings: List<RtkConnectedMeeting>, parentMeeting: RtkConnectedMeeting?) {
        println("State updated. Meetings: $meetings, Parent: $parentMeeting")

        // Alternatively, access state directly from the connectedMeetings object
        println("Meetings List: ${meeting.connectedMeetings.meetings}")
        println("Parent Meeting: ${meeting.connectedMeetings.parentMeeting}")
    }

    override fun onChangingMeeting(meetingId: String) {}
    override fun onMeetingChanged(error: MeetingError?) {}
})
meeting.connectedMeetings.deleteMeetings(meetingIds: ["MEETING_ID_TO_CLOSE_1", "MEETING_ID_TO_CLOSE_2"]) { error in
    if let error = error {
        print("Failed to close breakout rooms: \(error)")
    } else {
        print("Breakout rooms closed successfully")
    }
}

Это также вызовет onStateUpdate событие, обновляющее список сессионных залов и участников.

class MyListener: RtkConnectedMeetingsEventListener {
    func onStateUpdate(meetings: [RtkConnectedMeeting], parentMeeting: RtkConnectedMeeting?) {
        print("State updated. Meetings: \(meetings), Parent: \(String(describing: parentMeeting))")

        // Alternatively, access state directly from the connectedMeetings object
        print("Meetings List: \(meeting.connectedMeetings.meetings)")
        print("Parent Meeting: \(String(describing: meeting.connectedMeetings.parentMeeting))")
    }

    func onChangingMeeting(meetingId: String) {}
    func onMeetingChanged(error: MeetingError?) {}
}

meeting.addConnectedMeetingsEventListener(MyListener())
await meeting.connectedMeetings.deleteMeetings([
  "MEETING_ID_TO_CLOSE_1",
  "MEETING_ID_TO_CLOSE_2",
]);

Это также вызвало бы stateUpdate событие, обновляющее список сессионных залов и участников.

meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
  console.log("stateUpdate", {meetings, parentMeeting});
});

// Alternatively, you can access the meetings and parentMeeting from the connectedMeetings object
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);

Следующие шаги

Вы успешно интегрировали сессионные залы в своё приложение RealtimeKit. Теперь участники могут:

Для более продвинутой настройки ознакомьтесь со следующим: