← Cloudflare Realtime / realtime / realtimekit / ui-kit
Управление состоянием
Предварительные требования
Эта страница опирается на Руководство по базовой реализации. Сначала обязательно изучите их.
Примеры кода на этой странице предполагают, что вы уже импортировали необходимые пакеты и инициализировали SDK.
Как компоненты UI Kit взаимодействуют друг с другом
Компоненты UI Kit способны понимать друг друга и синхронизироваться друг с другом, поскольку они вложены в RtkMeeting компонент. RtkMeeting компонент выступает в роли центрального координатора, который обеспечивает синхронизацию всех вложенных в него компонентов по состоянию встречи, обновлениям участников и другим изменениям в реальном времени.
Компоненты UI Kit способны понимать друг друга и синхронизироваться друг с другом, поскольку они вложены в rtk-meeting компонент. rtk-meeting компонент выступает в роли центрального координатора, который обеспечивает синхронизацию всех вложенных в него компонентов по состоянию встречи, обновлениям участников и другим изменениям в реальном времени.
Компоненты UI Kit способны понимать друг друга и синхронизироваться друг с другом, поскольку они вложены в rtk-meeting компонент. rtk-meeting компонент выступает в роли центрального координатора, который обеспечивает синхронизацию всех вложенных в него компонентов по состоянию встречи, обновлениям участников и другим изменениям в реальном времени.
Android UI Kit самостоятельно управляет взаимодействием компонентов. При сборке UI Kit с помощью RealtimeKitUIBuilder, он создаёт и координирует все необходимые UI-компоненты. Чтобы отслеживать изменения состояния встречи из вашего приложения, подключите слушатели к событиям Core SDK meeting объект.
iOS UI Kit внутренне управляет взаимодействием компонентов через RealtimeKitUI модуль. Чтобы отслеживать изменения состояния встречи из вашего приложения, реализуйте протоколы обработчиков событий и зарегистрируйте их в модуле Core SDK meeting объект.
Компоненты React Native UI Kit взаимодействуют и синхронизируются друг с другом, поскольку они вложены в RtkMeeting компонент, обёрнутый в RealtimeKitProvider и RtkUIProvider. Чтобы отслеживать изменения состояния, используйте хуки из Core SDK, например useRealtimeKitSelector.
Ниже приведен пример того, как работает синхронизация состояния при открытии боковой панели участников:
flowchart LR
accTitle: Sidebar State Synchronization Example
accDescr: Example showing how clicking participants toggle updates sidebar through meeting coordination
Toggle["👤 ParticipantsToggle<br/>(User clicks)"]
Meeting["Meeting Component<br/>(State Coordinator)"]
Sidebar["Sidebar<br/>(Opens/Closes)"]
App["Your App<br/>(Gets notified)"]
Toggle -->|"emits rtkStateUpdate<br/>{activeSidebar: true,<br/>sidebar: 'participants'}"|Meeting
Meeting -->|"propagates state"|Sidebar
Meeting -->|"emits rtkStatesUpdate"|App
style Meeting fill:#F48120,stroke:#333,stroke-width:2px,color:#fff
style App fill:#0051C3,stroke:#333,stroke-width:2px,color:#fff
Поток состояний
- Дочерние компоненты передают обновления состояния: Когда любому UI-компоненту нужно обновить состояние, он генерирует
rtkStateUpdateсобытие - Компонент встречи прослушивает события и координирует их: Компонент встречи прослушивает все эти события обновления состояния от своих дочерних компонентов
- Распространение состояния: Компонент встречи передает обновленное состояние всем остальным дочерним компонентам, чтобы поддерживать их синхронизацию
- Внешнее уведомление: Компонент встречи также генерирует
rtkStatesUpdateсобытие, на которое приложение может подписаться, чтобы обновлять собственный интерфейс или выполнять действия при изменении состояния
- UI Kit управляет внутренним состоянием: UI Kit самостоятельно обрабатывает взаимодействие компонентов и синхронизацию состояния
- Ваше приложение регистрирует слушателей событий: Вы подключаете обработчики событий (например,
RtkMeetingRoomEventListenerиRtkSelfEventListener) к элементу Core SDKmeetingобъект - Колбэки срабатывают при изменении состояния: При изменении состояния встречи (например, когда участник присоединяется или переключается звук) вызывается соответствующий обработчик
- Вы обновляете свой интерфейс: Используйте данные обратного вызова, чтобы обновить интерфейс приложения или запустить другие действия
- UI Kit управляет внутренним состоянием:
RtkMeetingкомпонент отвечает за всё внутреннее взаимодействие компонентов и синхронизацию состояния - Ваше приложение отслеживает состояние с помощью хуков: Используйте
useRealtimeKitSelectorчтобы выбирать конкретные свойства встречи и перерисовываться при их изменении - React выполняет повторный рендеринг при изменениях: При изменении выбранного значения React автоматически перерисовывает компонент с новым состоянием
- Вы обновляете свой интерфейс: Используйте наблюдаемые значения состояния, чтобы условно отображать элементы интерфейса или запускать побочные эффекты
Отслеживание обновлений состояния
Чтобы создать пользовательский интерфейс или выполнять действия на основе изменений состояния встречи, необходимо отслеживать обновления состояния из UI Kit.
Прослушивайте rtkStatesUpdate событие, генерируемое компонентом meeting. Оно передаёт текущее состояние UI Kit, включая состояние боковой панели, статус демонстрации экрана, тип отображения и другие параметры.
Подключите слушатели к событиям Core SDK meeting объект, чтобы отслеживать изменения состояния встречи. Мобильный UI Kit управляет собственным внутренним состоянием, поэтому ваше приложение напрямую взаимодействует с базовым объектом встречи.
Используйте useRealtimeKitSelector хук из @cloudflare/realtimekit-react-native чтобы отслеживать отдельные свойства объекта встречи. Этот хук перерисовывает ваш компонент при каждом изменении выбранного значения, аналогично тому, как работают селекторы в библиотеках управления состоянием.
Пример кода
Для React можно использовать onRtkStatesUpdate prop в RtkMeeting компонент для отслеживания обновлений состояния.
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>");
const [states, setStates] = useState({});
useEffect(() => {
if (authToken) {
initMeeting({
authToken: authToken,
});
}
}, [authToken]);
return (
<RealtimeKitProvider value={meeting}>
<RtkMeeting
showSetupScreen={true}
meeting={meeting}
onRtkStatesUpdate={(e) => {
// Update states when rtk-meeting emits state updates
setStates(e.detail);
// Example: Access various state properties
console.log("Meeting state:", e.detail.meeting); // 'idle', 'setup', 'joined', 'ended', 'waiting'
console.log("Is sidebar active:", e.detail.activeSidebar);
console.log("Current sidebar section:", e.detail.sidebar);
console.log("Is screen sharing:", e.detail.activeScreenShare);
}}
/>
{/* Use states to build custom UI */}
<div className="custom-ui">
<p>Meeting State: {states.meeting}</p>
<p>Sidebar Open: {states.activeSidebar ? "Yes" : "No"}</p>
</div>
</RealtimeKitProvider>
);
}Альтернатива: использование Refs (несколько встреч)
Если вы создаёте сценарий с несколькими встречами на одной странице или последовательными встречами, для предотвращения конфликтов состояния между разными экземплярами встречи рекомендуется использовать refs:
import {
RealtimeKitProvider,
useRealtimeKitClient,
} from "@cloudflare/realtimekit-react";
import { RtkMeeting } from "@cloudflare/realtimekit-react-ui";
import { useEffect, useState, useRef } from "react";
function App() {
const [meeting, initMeeting] = useRealtimeKitClient();
const [authToken, setAuthToken] = useState("<participant_auth_token>");
const [states, setStates] = useState({});
const meetingRef = useRef(null);
useEffect(() => {
if (authToken) {
initMeeting({
authToken: authToken,
});
}
}, [authToken]);
useEffect(() => {
if (!meetingRef.current) return;
const handleStatesUpdate = (e) => {
setStates(e.detail);
console.log("Meeting state:", e.detail.meeting);
console.log("Is sidebar active:", e.detail.activeSidebar);
};
// Add event listener via ref
meetingRef.current.addEventListener("rtkStatesUpdate", handleStatesUpdate);
// Cleanup listener when component unmounts or meeting changes
return () => {
meetingRef.current?.removeEventListener(
"rtkStatesUpdate",
handleStatesUpdate,
);
};
}, [meetingRef.current]);
return (
<RealtimeKitProvider value={meeting}>
<RtkMeeting ref={meetingRef} showSetupScreen={true} meeting={meeting} />
{/* Use states to build custom UI */}
<div className="custom-ui">
<p>Meeting State: {states.meeting}</p>
<p>Sidebar Open: {states.activeSidebar ? "Yes" : "No"}</p>
</div>
</RealtimeKitProvider>
);
}Для Web Components необходимо добавить обработчик события к rtk-meeting компонент для отслеживания rtkStatesUpdate события.
<body>
<rtk-meeting id="meeting-component"></rtk-meeting>
</body>
<script type="module">
import RealtimeKitClient from "https://cdn.jsdelivr.net/npm/@cloudflare/realtimekit@latest/dist/index.es.js";
const meeting = await RealtimeKitClient.init({
authToken: "<participant_auth_token>",
});
// Add <rtk-meeting id="meeting-component" /> to your HTML, otherwise you will get error
const meetingComponent = document.querySelector("#meeting-component");
// Listen for state updates from rtk-meeting
meetingComponent.addEventListener("rtkStatesUpdate", (event) => {
console.log("RTK states updated:", event.detail);
// Store states to update your custom UI
const states = event.detail;
// Example: Access various state properties
console.log("Meeting state:", states.meeting); // 'idle', 'setup', 'joined', 'ended', 'waiting'
console.log("Is sidebar active:", states.activeSidebar);
console.log("Current sidebar section:", states.sidebar); // 'chat', 'participants', 'polls', etc.
console.log("Is screen sharing:", states.activeScreenShare);
// Update your custom UI based on states
// For example: Show/hide elements based on meeting state
if (states.meeting === "joined") {
// Show meeting controls
}
});
meetingComponent.showSetupScreen = true;
meetingComponent.meeting = meeting;
</script>Для Angular необходимо добавить обработчик события к rtk-meeting компонент для отслеживания rtkStatesUpdate события.
import {
Component,
ElementRef,
OnInit,
OnDestroy,
ViewChild,
} from "@angular/core";
@Component({
selector: "app-meeting",
template: `
<rtk-meeting #meetingComponent id="meeting-component"></rtk-meeting>
<!-- Use states to build custom UI -->
<div class="custom-ui" *ngIf="states">
<p>Meeting State: {{ states.meeting }}</p>
<p>Sidebar Open: {{ states.activeSidebar ? "Yes" : "No" }}</p>
<div *ngIf="states.meeting === 'joined'" class="meeting-controls">
<!-- Show meeting controls when joined -->
<p>Meeting controls would go here</p>
</div>
</div>
`,
styleUrls: ["./meeting.component.css"],
})
export class MeetingComponent implements OnInit, OnDestroy {
@ViewChild("meetingComponent", { static: true }) meetingElement!: ElementRef;
meeting: any;
states: any = {};
private authToken = "<participant_auth_token>";
private stateUpdateListener?: (event: any) => void;
async ngOnInit() {
// Import RealtimeKit client dynamically
const RealtimeKitClient = await import(
"https://cdn.jsdelivr.net/npm/@cloudflare/realtimekit@latest/dist/index.es.js"
);
// Initialize the meeting
this.meeting = await RealtimeKitClient.default.init({
authToken: this.authToken,
});
// Set up the meeting component
const meetingComponent = this.meetingElement.nativeElement;
// Create the event listener
this.stateUpdateListener = (event: any) => {
console.log("RTK states updated:", event.detail);
// Store states to update your custom UI
this.states = event.detail;
// Example: Access various state properties
console.log("Meeting state:", this.states.meeting); // 'idle', 'setup', 'joined', 'ended', 'waiting'
console.log("Is sidebar active:", this.states.activeSidebar);
console.log("Current sidebar section:", this.states.sidebar); // 'chat', 'participants', 'polls', etc.
console.log("Is screen sharing:", this.states.activeScreenShare);
// Update your custom UI based on states
// For example: Show/hide elements based on meeting state
if (this.states.meeting === "joined") {
// Show meeting controls
console.log("Meeting joined - showing controls");
}
};
// Listen for state updates from rtk-meeting
meetingComponent.addEventListener(
"rtkStatesUpdate",
this.stateUpdateListener,
);
// Configure the meeting component
meetingComponent.showSetupScreen = true;
meetingComponent.meeting = this.meeting;
}
ngOnDestroy() {
// Clean up event listener when component is destroyed
if (this.stateUpdateListener && this.meetingElement) {
this.meetingElement.nativeElement.removeEventListener(
"rtkStatesUpdate",
this.stateUpdateListener,
);
}
}
}Для Android подключите слушатели к событиям meeting объект, чтобы отслеживать изменения состояния. Используйте RtkMeetingRoomEventListener для событий жизненного цикла встречи и RtkSelfEventListener для изменений состояния локального участника.
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class MeetingActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// After initializing the meeting and UI Kit (see Getting Started guide),
// add event listeners to observe state changes.
// Listen for meeting room state changes
meeting.addMeetingRoomEventListener(object : RtkMeetingRoomEventListener {
override fun onMeetingRoomJoinStarted() {
Log.d("Meeting", "Join started")
}
override fun onMeetingRoomJoinCompleted(meeting: RealtimeKitClient) {
Log.d("Meeting", "Joined the meeting")
// Update UI to show meeting controls
}
override fun onMeetingRoomJoinFailed(exception: Exception) {
Log.e("Meeting", "Join failed: ${exception.message}")
}
override fun onMeetingRoomLeaveStarted() {
Log.d("Meeting", "Leave started")
}
override fun onMeetingRoomLeft() {
Log.d("Meeting", "Left the meeting")
}
override fun onMeetingEnded() {
Log.d("Meeting", "Meeting ended for all participants")
}
override fun onActiveTabUpdate(activeTab: ActiveTab) {
Log.d("Meeting", "Active tab changed: $activeTab")
}
})
// Listen for local participant state changes
meeting.addSelfEventListener(object : RtkSelfEventListener {
override fun onAudioUpdate(isEnabled: Boolean) {
Log.d("Meeting", "Audio: ${if (isEnabled) "on" else "off"}")
}
override fun onVideoUpdate(isEnabled: Boolean) {
Log.d("Meeting", "Video: ${if (isEnabled) "on" else "off"}")
}
override fun onRemovedFromMeeting() {
Log.d("Meeting", "Removed from meeting by host")
}
})
}
}Для iOS реализуйте протоколы обработчиков событий и зарегистрируйте их в meeting объект. Используйте RtkMeetingRoomEventListener для событий жизненного цикла встречи и RtkSelfEventListener для изменений состояния локального участника.
// Listen for meeting room state changes
extension MeetingViewModel: RtkMeetingRoomEventListener {
func onMeetingRoomJoinCompleted(meeting: RealtimeKitClient) {
// Successfully joined the meeting (equivalent to 'joined' state)
}
func onMeetingRoomLeft() {
// Successfully left the meeting
}
func onMeetingEnded() {
// The meeting has ended for all participants (equivalent to 'ended' state)
}
func onActiveTabUpdate(activeTab: ActiveTab) {
// Active tab changed (e.g., chat, polls, participants)
// Use this to sync your custom UI with the active sidebar section
}
}
// Listen for local participant state changes
extension MeetingViewModel: RtkSelfEventListener {
func onAudioUpdate(isEnabled: Bool) {
// Audio toggled on/off
}
func onVideoUpdate(isEnabled: Bool) {
// Video toggled on/off
}
func onRemovedFromMeeting() {
// Local user was removed from the meeting by host
}
}
// Register the listeners
meeting.addMeetingRoomEventListener(meetingRoomEventListener: self)
meeting.addSelfEventListener(selfEventListener: self)Для React Native используйте useRealtimeKitSelector хук для отслеживания отдельных свойств объекта встречи. Этот подход аналогичен веб-версии Core SDK.
import { useEffect } from "react";
import { View, Text } from "react-native";
import {
RealtimeKitProvider,
useRealtimeKitClient,
useRealtimeKitMeeting,
useRealtimeKitSelector,
} from "@cloudflare/realtimekit-react-native";
import {
RtkUIProvider,
RtkMeeting,
} from "@cloudflare/realtimekit-react-native-ui";
function App() {
const [meeting, initMeeting] = useRealtimeKitClient();
useEffect(() => {
initMeeting({
authToken: "<participant_auth_token>",
defaults: { audio: true, video: true },
});
}, []);
return (
<RealtimeKitProvider value={meeting}>
<RtkUIProvider>
<MeetingWithState />
</RtkUIProvider>
</RealtimeKitProvider>
);
}
function MeetingWithState() {
const { meeting } = useRealtimeKitMeeting();
// Use selectors to observe meeting state
const roomState = useRealtimeKitSelector((m) => m.self.roomState);
const audioEnabled = useRealtimeKitSelector((m) => m.self.audioEnabled);
const videoEnabled = useRealtimeKitSelector((m) => m.self.videoEnabled);
useEffect(() => {
console.log("Room state:", roomState);
console.log("Audio:", audioEnabled);
console.log("Video:", videoEnabled);
}, [roomState, audioEnabled, videoEnabled]);
return (
<View>
{meeting && <RtkMeeting meeting={meeting} showSetupScreen={true} />}
{/* Use state to build custom UI */}
<View>
<Text>Room State: {roomState}</Text>
<Text>Audio: {audioEnabled ? "On" : "Off"}</Text>
<Text>Video: {videoEnabled ? "On" : "Off"}</Text>
</View>
</View>
);
}Альтернатива: использование обработчиков событий
Для более точного контроля также можно использовать слушателей на основе событий, как в веб Core SDK:
import { useEffect } from "react";
function MeetingEvents() {
const { meeting } = useRealtimeKitMeeting();
useEffect(() => {
if (!meeting) return;
const handleRoomJoined = () => {
console.log("Successfully joined the meeting");
};
const handleRoomLeft = ({ state }) => {
if (state === "ended") {
console.log("Meeting ended");
}
};
meeting.self.on("roomJoined", handleRoomJoined);
meeting.self.on("roomLeft", handleRoomLeft);
return () => {
meeting.self.removeListener("roomJoined", handleRoomJoined);
meeting.self.removeListener("roomLeft", handleRoomLeft);
};
}, [meeting]);
return null;
}Свойства состояния
rtkStatesUpdate событие содержит подробную информацию о внутреннем состоянии UI Kit. Основные свойства:
meeting: Текущее состояние встречи:'idle','setup','joined','ended', или'waiting'activeSidebar: Открыта ли в данный момент боковая панель (boolean)sidebar: Текущий раздел боковой панели:'chat','participants','polls','plugins', и т. д.activeScreenShare: Активен ли интерфейс демонстрации экрана (boolean)activeMoreMenu: Открыто ли меню «Ещё» (boolean)activeSettings: Открыта ли панель настроек (boolean)viewType: Текущий тип отображения видеосетки (string)prefs: Объект пользовательских настроек (например,mirrorVideo,muteNotificationSounds)roomLeftState: Состояние при выходе из комнатыactiveOverlayModal: объект конфигурации активного оверлейного модального окнаactiveConfirmationModal: объект конфигурации активного модального окна подтверждения- И ещё множество других свойств состояния UI
На мобильных платформах состояние отслеживается через обработчики событий Core SDK, а не через единый объект состояния. Основные обработчики событий и их колбэки:
RtkMeetingRoomEventListener - Жизненный цикл встречи:
onMeetingRoomJoinStarted: Начался процесс присоединения к встречеonMeetingRoomJoinCompleted: Успешное присоединение к встречеonMeetingRoomJoinFailed: Не удалось присоединиться к встрече (содержит сведения об исключении)onMeetingRoomLeaveStarted: Начался процесс выходаonMeetingRoomLeft: Успешный выход из встречиonMeetingEnded: Встреча завершена для всех участниковonActiveTabUpdate: изменилась активная вкладка боковой панели (чат, опросы, участники)
RtkSelfEventListener - Локальный участник:
onAudioUpdate: аудио включено или выключеноonVideoUpdate: Видео включено или выключеноonRemovedFromMeeting: Локальный пользователь был удалён организатором
RtkParticipantsEventListener - Удалённые участники:
onParticipantJoin: участник присоединился к встречеonParticipantLeave: участник покинул встречуonActiveParticipantsChanged: изменился список активных участниковonAudioUpdate: изменилось состояние аудио удаленного участникаonVideoUpdate: изменилось состояние видео удаленного участника
В React Native используйте useRealtimeKitSelector хук для отслеживания отдельных свойств объекта встречи. Основные свойства:
m.self.roomState: Текущее состояние комнаты ('init','joined','left', и т. д.)m.self.audioEnabled: Включено ли локальное аудио (boolean)m.self.videoEnabled: Включено ли локальное видео (boolean)m.self.screenShareEnabled: Активна ли демонстрация экрана (boolean)m.self.name: Отображаемое имя локального участникаm.self.id: Peer ID локального участникаm.participants.joined: Список присоединившихся участниковm.participants.active: Список активных участников
Лучшие практики
- Храните состояния надлежащим образом: В React используйте
useStateхук или библиотеку управления состоянием (например, Zustand или Redux) для приложений на React. Для обычного JavaScript используйте решение для реактивного управления состоянием или простое хранение в объекте. - Снижает количество избыточных перерисовок: Обновляйте интерфейс только при необходимости. В React рекомендуется использовать
useMemoилиuseCallbackдля оптимизации производительности. - Безопасный доступ к вложенным свойствам: всегда проверяйте, существуют ли вложенные свойства, прежде чем обращаться к ним (например,
states.sidebar,states.prefs?.mirrorVideo). - Используйте состояния для условного рендеринга: Используйте состояния UI, чтобы показывать или скрывать элементы интерфейса либо реагировать на изменения интерфейса (например, показывать собственные индикаторы, когда
states.activeScreenShareравно true). - Изучите разницу:
rtkStatesUpdateпредоставляет внутренние состояния UI Kit для управления интерфейсом. Для данных встречи (участники, активный докладчик, статус записи) используйтеmeetingобъект и его события напрямую.
- Удаляйте обработчики при очистке: всегда удаляйте обработчики событий в
onDestroy()чтобы предотвратить утечки памяти. Сохраняйте ссылки на слушателей, чтобы позже иметь возможность их отписать. - Используйте подходящую многопоточность: Обратные вызовы обработчиков событий могут срабатывать в фоновых потоках. Используйте
runOnUiThreadили отправляйте в основной обработчик при обновлении элементов интерфейса. - Храните состояние в наблюдаемых паттернах: Используйте
LiveData,StateFlow, илиMutableState(Compose) для реактивной передачи изменений состояния в ваш UI. - Изучите разницу: Обработчики событий предоставляют жизненный цикл встречи и состояние участников изменения. UI Kit управляет собственным внутренним состоянием интерфейса отдельно.
- Удаляйте обработчики при очистке: всегда удаляйте обработчики событий при освобождении view controller или view model, чтобы избежать циклов удержания и утечек памяти.
- Используйте
@Publishedдля реактивного интерфейса: В SwiftUI отмечайте свойства состояния как@Publishedв вашемObservableObjectчтобы автоматически перерисовывать представления при изменении состояния встречи. - Обработка потоков: Обратные вызовы обработчиков событий могут срабатывать в фоновых потоках. Используйте
DispatchQueue.main.asyncпри обновлении элементов интерфейса из колбэков. - Изучите разницу: Обработчики событий предоставляют жизненный цикл встречи и состояние участников изменения. UI Kit управляет собственным внутренним состоянием интерфейса отдельно.
- Используйте селекторы для повышения эффективности:
useRealtimeKitSelectorхук перерисовывает ваш компонент только при изменении выбранного значения. Выбирайте только те свойства, которые вам действительно нужны, а не весь объект встречи. - Очистите обработчики событий: При использовании
meeting.self.on()обработчиков этого события всегда возвращайте функцию очистки изuseEffectкоторый вызываетremoveListener. - Сочетание с
useMemoиuseCallback: Используйте хуки мемоизации React, чтобы избежать лишних повторных рендеров при частом изменении состояния встречи. - Изучите разницу:
useRealtimeKitSelectorпредоставляет доступ к Состояние встречи в Core SDK (участники, медиаданные, состояние комнаты). UI Kit управляет собственным внутренним состоянием интерфейса черезRtkMeetingкомпонент.