分组讨论室允许会议参与者分成较小的组,进行有针对性的讨论和协作。随着远程办公和在线学习的兴起,分组讨论室已成为在虚拟环境中增强参与度和建设社区的重要工具。它们是研讨会、在线课堂或当您需要在主会议之外与选定参与者进行私密交流时的理想选择。
在 RealtimeKit 中,分组讨论室是作为单独的会议创建的。每个分组讨论室都是一个独立的会议,可以像任何其他 RealtimeKit 会议一样进行管理。RealtimeKit 提供了一组 SDK API,用于创建、管理和在分组讨论室之间切换。
以下是 RealtimeKit 分组讨论室的一些主要特性:
- 使用预设管理主持人与参与者的权限和特权
- 主持人可以创建分组讨论室、分配参与者、开始和关闭分组讨论室以及在不同的讨论室之间切换
- 参与者可以开始和停止视频,使用聊天和投票功能与其他参与者互动,以及静音/取消静音音频
- 像任何其他 RealtimeKit 会议一样单独录制所有分组会话
分组讨论室中的角色由预设进行管理。
主持人可以创建分组讨论室、分配参与者、开始和关闭分组讨论室以及在讨论室之间切换。
作为分组讨论室中的参与者,您可以:
- Switch to Parent Meeting(切换到主会议) - 返回主会议(如果您拥有所需的权限)
- Switch Connected Meetings(切换关联会议) - 从主会议移动到更小的、有针对性的讨论组(分组讨论室)进行协作
- 协作 - 在分组会话期间使用聊天和投票等工具
每个分组讨论室都作为一个独立的会议运行。当您从主会议切换到分组讨论室时,它会自动切换到分组会话的音频和视频。在分组会话期间,您可以随时静音或取消静音音频,以及开始或停止视频,就像在主会议中一样。
当分组会话结束时,您的音频和视频会自动切换回主会议。
- 如果您的视频在分组会话期间是开启状态,则在返回主会话时它将保持开启状态
- 如果您的麦克风在分组会话期间是开启状态,则在返回主会话时它将保持开启状态
每个分组会话都是一个独立的会话。每个分组会话的录制均单独存储和管理,就像任何其他 RealtimeKit 会议一样。有关更多信息,请参阅录制。
分组讨论室允许参与者分成独立的会话。主持人可以创建分组讨论室、分配参与者、开始和关闭分组讨论室。
预设是应用于主持人和参与者的一组权限和 UI 配置。它们决定了分组讨论室的外观、感觉和行为。
对于分组讨论室,您必须在 Connected Meetings 中为主持人和参与者提供以下权限:
主持人预设应在 Connected Meetings 中具有 Full Access(完全访问) 权限。这允许主持人:
- 创建分组讨论室
- 分配参与者到讨论室
- 开始和关闭分组讨论室
- 在讨论室之间切换
您可以选择向参与者提供以下权限:
- Switch Connected Meetings(切换关联会议) - 允许参与者在分组讨论室之间移动
- Switch to Parent Meeting(切换到主会议) - 允许参与者返回主会议
- 对预设进行所有更改后,单击 Save(保存)
- 输入您的预设名称,然后单击 Save(保存)
- 您的预设将被列出 - 单击 **Edit(编辑)**以进行任何更改
使用 Create meeting API 创建 RealtimeKit 会议。此 API 会返回您会议的唯一标识符。
创建会议后,使用 Add participant API 添加每个参与者。之前创建的 presetName 必须在 Add Participant API 请求的请求体中传递。
在创建分组讨论室之前,验证当前参与者的权限,以确保参与者具有创建分组讨论室所需的权限。权限不正确可能会导致抛出错误。
// 检查是否支持分组讨论室
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;
// 检查是否已经创建了任何分组讨论室
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;
// 检查当前参与者是否有权限创建分组讨论室
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;
// 检查当前参与者是否有权限切换回主会议
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;
// 检查当前参与者是否有权限切换到关联的讨论室
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;// 检查是否支持分组讨论室
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;
// 检查是否已经创建了任何分组讨论室
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;
// 检查当前参与者是否有权限创建分组讨论室
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;
// 检查当前参与者是否有权限切换回主会议
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;
// 检查当前参与者是否有权限切换到关联的讨论室
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;// 检查是否支持分组讨论室
const areBreakoutRoomsSupported = meeting.connectedMeetings.supportsConnectedMeetings;
// 检查是否已经创建了任何分组讨论室
const areBreakoutRoomsActive = meeting.connectedMeetings.isActive;
// 检查当前参与者是否有权限创建分组讨论室
const hasPermissionToCreateBreakoutRooms = meeting.self.permissions.connectedMeetings.canAlterConnectedMeetings;
// 检查当前参与者是否有权限切换回主会议
const hasPermissionToSwitchToParentMeeting = meeting.self.permissions.connectedMeetings.canSwitchToParentMeeting;
// 检查当前参与者是否有权限切换到关联的讨论室
const hasPermissionToSwitchToConnectedMeeting = meeting.self.permissions.connectedMeetings.canSwitchConnectedMeetings;val connectedMeetings = meeting.connectedMeetings
// 检查分组会议室是否处于活动状态
val areBreakoutRoomsActive = connectedMeetings.isActive
// 检查本地参与者的权限
val permissions = meeting.self.permissions.connectedMeetings
// 检查当前参与者是否具有创建/修改分组会议室的权限
val hasPermissionToAlterBreakoutRooms = permissions.canAlterConnectedMeetings
// 检查当前参与者是否具有在分组会议室之间切换的权限
val hasPermissionToSwitchConnectedMeetings = permissions.canSwitchConnectedMeetings
// 检查当前参与者是否具有切换回主会议的权限
val hasPermissionToSwitchToParentMeeting = permissions.canSwitchToParentMeetinglet connectedMeetings = meeting.connectedMeetings
// 检查分组讨论室是否处于活动状态
let areBreakoutRoomsActive = connectedMeetings.isActive
// 检查本地参与者的权限
let permissions = meeting.self.permissions.connectedMeetings
// 检查当前参与者是否有权限创建/修改分组讨论室
let hasPermissionToAlterBreakoutRooms = permissions.canAlterConnectedMeetings
// 检查当前参与者是否有权限在分组讨论室之间切换
let hasPermissionToSwitchConnectedMeetings = permissions.canSwitchConnectedMeetings
// 检查当前参与者是否有权限切换回主会议
let hasPermissionToSwitchToParentMeeting = permissions.canSwitchToParentMeetingconst [meeting] = useRealtimeKitClient();
// 检查当前是否有任何分组讨论室处于活动状态
const areBreakoutRoomsActive = meeting?.connectedMeetings.isActive;
// 检查本地参与者是否可以创建、重命名或删除讨论室以及移动任何参与者
const canAlterBreakoutRooms = meeting?.self.permissions.connectedMeetings.canAlterConnectedMeetings;
// 检查本地参与者是否可以自行切换到任何分组讨论室
const canSwitchRooms = meeting?.self.permissions.connectedMeetings.canSwitchConnectedMeetings;
// 检查本地参与者是否可以返回主会议
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 是一个包含分组讨论室及其参与者列表以及主会议详细信息的对象。
此数据可用于在 UI 中显示分组讨论室和参与者的列表。此 API 会重新获取分组讨论室和参与者的列表,因此可以被视为分组讨论室和参与者的唯一可信数据源。如果正在进行大量更改,建议调用此 API 以获取分组讨论室和参与者的最新列表。
您还可以监听 stateUpdate 事件,以在实时更新时获取分组讨论室和参与者的最新列表。
meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
console.log("stateUpdate", {meetings, parentMeeting});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
});const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();breakoutRoomsInfo 是一个包含分组讨论室及其参与者列表以及主会议详细信息的对象。
此数据可用于在 UI 中显示分组讨论室和参与者的列表。此 API 会重新获取分组讨论室和参与者的列表,因此可以被视为分组讨论室和参与者的唯一可信数据源。如果正在进行大量更改,建议调用此 API 以获取分组讨论室和参与者的最新列表。
您还可以监听 stateUpdate 事件,以在实时更新时获取分组讨论室和参与者的最新列表。
meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
console.log("stateUpdate", {meetings, parentMeeting});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
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 是一个包含分组讨论室及其参与者列表,以及主会议(parent meeting)详细信息的对象。
此数据可用于在 UI 中显示分组讨论室和参与者的列表。此 API 重新获取分组讨论室和参与者的列表,因此可被视为单一可信源(source of truth)。如果正在进行大量更改,建议调用此 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 是一个包含分组讨论室及其参与者列表以及主会议详细信息的对象。
此数据可用于在 UI 中显示分组讨论室和参与者的列表。此 API 会重新获取分组讨论室和参与者的列表,因此可以被视为唯一可信数据源。如果正在进行大量更改,建议调用此 API 以获取最新状态。
您还可以监听 onStateUpdate 事件,以接收分组讨论室和参与者列表的实时更新。
class MyListener: RtkConnectedMeetingsEventListener {
func onStateUpdate(meetings: [RtkConnectedMeeting], parentMeeting: RtkConnectedMeeting?) {
print("State updated. Meetings: \(meetings), Parent: \(String(describing: parentMeeting))")
// 或者,直接从 connectedMeetings 对象访问状态
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 是一个包含分组讨论室及其参与者列表以及主会议详细信息的对象。
此数据可用于在 UI 中显示分组讨论室和参与者的列表。此 API 会重新获取分组讨论室和参与者的列表,因此可以被视为分组讨论室和参与者的唯一可信数据源。如果正在进行大量更改,建议调用此 API 以获取分组讨论室和参与者的最新列表。
您还可以监听 stateUpdate 事件,以在实时更新时获取分组讨论室和参与者的最新列表。
meeting.connectedMeetings.on("stateUpdate", ({meetings, parentMeeting}) => {
console.log("stateUpdate", {meetings, parentMeeting});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);
});创建分组讨论室后,将参与者分配到这些讨论室。
// 获取分组讨论室和参与者列表
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();
/*
* 您可以从 breakoutRoomsInfo 对象中检索 meetingIds 和 participantIds。
* 根据参与者当前所在的位置,您可以决定 sourceMeetingId 和 targetMeetingId。
*/
// 将参与者移至分组讨论室
const response = await meeting.connectedMeetings.moveParticipants(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds,要移动的参与者 id 数组
);// 获取分组讨论室和参与者列表
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();
/*
* 您可以从 breakoutRoomsInfo 对象中检索 meetingIds 和 participantIds。
* 根据参与者当前所在的位置,您可以决定 sourceMeetingId 和 targetMeetingId。
*/
// 将参与者移至分组讨论室
const response = await meeting.connectedMeetings.moveParticipants(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds,要移动的参与者 id 数组
);// 获取分组讨论室和参与者列表
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();
/*
* 您可以从 breakoutRoomsInfo 对象中检索 meetingIds 和 participantIds。
* 根据参与者当前所在的位置,您可以决定 sourceMeetingId 和 targetMeetingId。
*/
// 将参与者移至分组讨论室
const response = await meeting.connectedMeetings.moveParticipants(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds,要移动的参与者 id 数组
);// 获取分组会议室和参与者列表
meeting.connectedMeetings.getConnectedMeetings { result ->
result.onSuccess { breakoutRoomsInfo ->
/*
* 你可以从 breakoutRoomsInfo 中获取 meetingIds 和 participantIds。
* 根据参与者当前的所在位置,决定 sourceMeetingId 和 targetMeetingId。
*/
// 将参与者移动到分组会议室
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")
}
}
}
}// 获取分组讨论室和参与者列表
meeting.connectedMeetings.getConnectedMeetings { result in
switch result {
case .success(let breakoutRoomsInfo):
/*
* 您可以从 breakoutRoomsInfo 中检索 meetingIds 和 participantIds。
* 根据参与者当前所在的位置,决定 fromMeetingId 和 toMeetingId。
*/
// 将参与者移至分组讨论室
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)")
}
}// 获取分组讨论室和参与者列表
const breakoutRoomsInfo = await meeting.connectedMeetings.getConnectedMeetings();
/*
* 您可以从 breakoutRoomsInfo 对象中检索 meetingIds 和 participantIds。
* 根据参与者当前所在的位置,您可以决定 sourceMeetingId 和 targetMeetingId。
*/
// 将参与者移至分组讨论室
const response = await meeting.connectedMeetings.moveParticipants(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
["PARTICIPANT_ID_1", "PARTICIPANT_ID_2"], // participantIds,要移动的参与者 id 数组
);创建分组讨论室后,将参与者分配到这些讨论室。
const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
[{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // 带有 presetId 字段的对象数组
);const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
[{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // 带有 presetId 字段的对象数组
);const response = await meeting.connectedMeetings.moveParticipantsWithCustomPreset(
"SOURCE_MEETING_ID", // sourceMeetingId,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
[{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // 带有 presetId 字段的对象数组
);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,参与者当前所在的会议 id
"TARGET_MEETING_ID", // targetMeetingId,参与者要移动到的会议 id
[{ presetId: "PRESET_ID_1" }, { presetId: "PRESET_ID_2" }], // 带有 presetId 字段的对象数组
);要将本地参与者移动到不同的分组讨论室或返回父会议,请使用与移动其他参与者相同的 API,但传入本地参与者的 ID。如果该请求是由非主持人的本地参与者发起的,则本地参与者必须具有相应的权限:canSwitchConnectedMeetings 用于在分组讨论室之间切换,或 canSwitchToParentMeeting 用于返回父会议。
如果参与者已被移动到分组讨论室,则会触发 changingMeeting 事件,随后触发 meetingChanged 事件。当参与者在主会议和分组讨论室之间切换时,也会触发这些事件。如果参与者被分配到分组讨论室,他们将自动加入。您无需显式加入会议。
// 监听 changingMeeting 事件以显示自定义 UI,指示正在进行会议切换
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");
});
// 监听 meetingChanged 事件以更新会议对象引用
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");
});// 监听 changingMeeting 事件以显示自定义 UI,指示正在进行会议切换
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");
});
// 监听 meetingChanged 事件以更新会议对象引用
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");
});// 监听 changingMeeting 事件以显示自定义 UI,指示正在进行会议切换
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");
});
// 监听 meetingChanged 事件以更新会议对象引用
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 {
// 启动会议切换时触发 — 使用此功能显示加载 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")
}
// 会议切换完成时触发
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 {
// 会议切换启动时触发 — 使用它来显示加载 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")
}
// 会议切换完成时触发
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 组件,过渡 UI(“正在加入……”屏幕)也会自动处理。
要在切换期间显示自定义加载屏幕,请监听 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});
});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
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});
});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
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});
});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
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 事件,更新分组讨论室(breakout room)和参与者的列表。
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))")
// 或者,直接从 connectedMeetings 对象访问状态
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});
});
// 或者,您也可以从 connectedMeetings 对象访问 meetings 和 parentMeeting
console.log("Meetings List", meeting.connectedMeetings.meetings);
console.log("Parent Meeting", meeting.connectedMeetings.parentMeeting);您已成功将分组讨论室集成到您的 RealtimeKit 应用程序中。参与者现在可以:
- 加入主会议
- 由主持人分配到分组讨论室
- 在主会议和分组讨论室之间切换
- 在更小、更专注的小组中进行协作
如需更高级的自定义,请探索以下内容:
- UI Kit 组件库 - 浏览可用组件
- UI Kit 状态 - 了解组件如何同步
- 构建您自己的 UI - 创建自定义会议界面