Breakout Rooms (2)·续

The meetingChanged event is triggered when a participant switches between the main meeting and breakout rooms. Update the meeting object reference when this event fires.

When using RealtimeKitUI.startMeeting(), the SDK automatically manages the RtkConnectedMeetingsListener — no extra setup is required for breakout room switching.

If you are building a custom meeting UI (bypassing MeetingViewController), register the listener yourself:

import RealtimeKit
import RealtimeKitUI

let listener = RtkConnectedMeetingsListener(rtkClient: rtkClient)

listener.onChangingMeeting = { meetingId in
    // Show a loading overlay; the SDK is switching rooms
    let isReturningToMain = meetingId == rtkClient.connectedMeetings.parentMeeting?.id
    showLoadingOverlay(message: isReturningToMain ? "Returning to Main Room\u{2026}" : "Joining breakout room\u{2026}")
}

listener.onMeetingChanged = { error in
    hideLoadingOverlay()
    if let error {
        showErrorAlert(message: error.message)
    } else {
        // Re-register all feature event listeners — the SDK clears them during the room switch
        // Re-register your listener instances, for example:
        // rtkClient.addSelfEventListener(selfEventListener: mySelfListener)
        // rtkClient.addParticipantsEventListener(participantsEventListener: myParticipantsListener)
    }
}

listener.onStateUpdate = { meetings, parentMeeting in
    // Refresh your breakout-rooms UI list
}

Note

Hold a strong reference to RtkConnectedMeetingsListener. It deregisters itself on deinit.

When using RealtimeKitUIBuilder + startMeeting(), the SDK automatically registers and manages RtkConnectedMeetingsEventListener — no extra setup is required for breakout room switching.

If you are building a custom meeting UI, register the listener yourself:

import com.cloudflare.realtimekit.ui.RtkConnectedMeetingsEventListener
import com.cloudflare.realtimekit.models.MeetingError

val connectedMeetingsListener = object : RtkConnectedMeetingsEventListener {
    override fun onChangingMeeting(meetingId: String) {
        // Show a transition screen; the SDK is switching rooms
        val isReturningToMain = meetingId == meeting.connectedMeetings.parentMeeting?.id
        showLoadingOverlay(isReturningToMain)
    }

override fun onMeetingChanged(error: MeetingError?) {
        hideLoadingOverlay()
        if (error != null) {
            showErrorMessage(error.message)
        }
        // No need to re-register listeners — the SDK handles this automatically
    }
}

meeting.addConnectedMeetingsEventListener(connectedMeetingsListener)

The onChangingMeeting callback fires when the SDK starts leaving the current room. The onMeetingChanged callback fires when the switch completes (or fails).

The useRealtimeKitClient hook automatically handles the meetingChanged event and swaps the active client reference when a participant moves between breakout rooms. No manual event handling is required.

import { useEffect } from "react";
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react-native";
import { RtkMeeting } from "@cloudflare/realtimekit-react-native-ui";

function App() {
  const [meeting, initMeeting] = useRealtimeKitClient();

useEffect(() => {
    initMeeting({ authToken: "<participant_auth_token>" });
  }, []);

if (!meeting) return null;

return <RtkMeeting meeting={meeting} showSetupScreen={true} />;
}

RtkMeeting displays a "Joining…" transition screen automatically when switching between breakout rooms. No extra setup is needed.

Render the meeting UI

Use the default meeting UI component which includes built-in breakout room support:

import {
    RealtimeKitProvider,
    useRealtimeKitClient,
} from "@cloudflare/realtimekit-react";
import { RtkMeeting } from "@cloudflare/realtimekit-react-ui";
import { useEffect, useState } from "react";

function App() {
    const [meeting, initMeeting] = useRealtimeKitClient();
    const [authToken, setAuthToken] = useState("<participant_auth_token>");

useEffect(() => {
        if (authToken) {
            initMeeting({
                authToken: authToken,
            });
        }
    }, [authToken]);

useEffect(() => {
        if (meeting) {
            meeting.connectedMeetings.on("meetingChanged", (newMeeting) => {
                console.log("Switched to breakout room or main meeting");
            });
        }
    }, [meeting]);

return (
        <RealtimeKitProvider value={meeting}>
            <RtkMeeting showSetupScreen={true} meeting={meeting} />
        </RealtimeKitProvider>
    );
}

Note

The Default Meeting UI (RtkMeeting component) automatically joins the session, so you do not need to call meeting.join().

The showSetupScreen property controls whether the setup screen is displayed, allowing participants to preview their audio and video before joining the session.

<body>
    <rtk-meeting id="my-meeting"></rtk-meeting>

<script type="module">
        import RealtimeKitClient from "https://cdn.jsdelivr.net/npm/@cloudflare/realtimekit@latest/dist/index.es.js";

let meeting = await RealtimeKitClient.init({
            authToken: "<participant_auth_token>",
        });

// Add event handler for breakout rooms
        meeting.connectedMeetings.on("meetingChanged", (newMeeting) => {
            meeting = newMeeting;
            document.querySelector("rtk-meeting").meeting = meeting;
        });

document.querySelector("rtk-meeting").showSetupScreen = true;
        document.querySelector("rtk-meeting").meeting = meeting;
    </script>
</body>

Note

The Default Meeting UI (rtk-meeting component) automatically joins the session, so you do not need to call meeting.join().

The showSetupScreen property controls whether the setup screen is displayed, allowing participants to preview their audio and video before joining the session.

<rtk-meeting #myid [showSetupScreen]="true"></rtk-meeting>
import { Component, ViewChild, AfterViewInit } from '@angular/core';
import RealtimeKitClient from '@cloudflare/realtimekit';
import { RtkMeeting } from '@cloudflare/realtimekit-angular-ui';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent implements AfterViewInit {
    @ViewChild('myid') meetingComponent: RtkMeeting;
    rtkMeeting: RealtimeKitClient;

async ngAfterViewInit() {
        let meeting = await RealtimeKitClient.init({
            authToken: '<participant_auth_token>',
        });

// Add event handler for breakout rooms
        meeting.connectedMeetings.on('meetingChanged', (newMeeting) => {
            meeting = newMeeting;
            if (this.meetingComponent) {
                this.meetingComponent.meeting = meeting;
            }
        });

this.rtkMeeting = meeting;
        if (this.meetingComponent) {
            this.meetingComponent.meeting = meeting;
        }
    }
}

Note

The Default Meeting UI (rtk-meeting component) automatically joins the session, so you do not need to call meeting.join().

The showSetupScreen property controls whether the setup screen is displayed, allowing participants to preview their audio and video before joining the session.

import RealtimeKit
import RealtimeKitUI

let meetingInfo = RtkMeetingInfo(authToken: "<participant_auth_token>")
let rtkUI = RealtimeKitUI(meetingInfo: meetingInfo)

let setupVC = rtkUI.startMeeting { [weak self] in
    // Called when the participant leaves or ends the meeting
    self?.dismiss(animated: true)
}
present(setupVC, animated: true)

Note

Like the web UI Kit, MeetingViewController automatically joins the session — you do not need to call meeting.join() manually.

The setup screen (audio/video preview) is shown by default. Built-in breakout room support — including the room-switching overlay and room title updates — is handled automatically by MeetingViewController.

import com.cloudflare.realtimekit.models.RtkMeetingInfo
import com.cloudflare.realtimekit.ui.RealtimeKitUIBuilder
import com.cloudflare.realtimekit.ui.RealtimeKitUIInfo

val meetingInfo = RtkMeetingInfo(authToken = "<participant_auth_token>")
val uiKitInfo = RealtimeKitUIInfo(
    activity = this,
    rtkMeetingInfo = meetingInfo,
)
val rtkUIKit = RealtimeKitUIBuilder.build(uiKitInfo)
rtkUIKit.startMeeting()

Note

RtkMeetingActivity automatically joins the session — you do not need to call meeting.join() manually.

Built-in breakout room support is handled automatically by RtkMeetingActivity. When the SDK moves participants between rooms, it displays a transition overlay with a localized message. The host can manage breakout rooms via the RtkBreakoutRoomsBottomSheet, which is shown automatically when the Breakout Rooms control bar button is tapped.

import { useEffect } from "react";
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react-native";
import { RtkMeeting } from "@cloudflare/realtimekit-react-native-ui";

function App() {
  const [meeting, initMeeting] = useRealtimeKitClient();

useEffect(() => {
    initMeeting({ authToken: "<participant_auth_token>" });
  }, []);

if (!meeting) return null;

return <RtkMeeting meeting={meeting} showSetupScreen={true} />;
}

Built-in breakout room support is handled automatically by RtkMeeting. When a participant is moved between rooms, a "Joining…" transition screen is displayed automatically. The host can manage breakout rooms using RtkBreakoutRoomsManager, which is accessible via RtkBreakoutRoomsToggle in the control bar.

Next steps

You have successfully integrated breakout rooms into your RealtimeKit application. Participants can now:

  • Join the main meeting
  • Be assigned to breakout rooms by the host
  • Switch between the main meeting and breakout rooms
  • Collaborate in smaller focused groups

For more advanced customization, explore the following:

Was this helpful?

YesNo

On this page

Breakout Rooms (2)·续 - 图1Docs

{"@context":"https://schema.org","@type":"WebPage","@id":"https://developers.cloudflare.com/realtime/realtimekit/humans/ui-kit/breakout-rooms/#page","headline":"Breakout Rooms","description":"Create and manage breakout rooms in RealtimeKit meetings for smaller group discussions.","url":"https://developers.cloudflare.com/realtime/realtimekit/humans/ui-kit/breakout-rooms/","inLanguage":"en","image":"https://developers.cloudflare.com/realtime/realtimekit/humans/ui-kit/breakout-rooms/og.png?v=2c58dd3ea3e8b2cb","dateModified":"2026-10-19","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Build a custom meeting interface video UI using RealtimeKit SDK components and Core SDK. title: Build Your Own UI image: https://developers.cloudflare.com/realtime/realtimekit/humans/ui-kit/build-your-own-ui/og.png?v=c556a149a1af1f54


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/realtime/llms.txt
Use this file to discover all available pages before exploring further.