Skip to main content

Leave, End, and Rejoin a Room

A close button can mean three different things. Choose the meaning before you wire the control:

IntentResult
Participant leavesThat participant disconnects; everyone else continues.
Host leaves and preserves the roomThe host disconnects; participants and room duration continue; the host may rejoin.
Host ends the roomThe room closes for everyone.

Do not implement any of these by navigating away first. Await the semantic room action, stop app-owned media, then unmount the runtime.

The default remains host end

For SDKs that expose endRoomOnHostExit, its default is true. This preserves the historical behavior: a host who uses the normal leave action ends the room. Pass false only from a control explicitly labelled, for example, Leave and keep room open. Never change the default globally to simulate this feature.

ReactJS 4.3.0

import { useState } from 'react';
import { useMediasfuHeadless } from 'mediasfu-reactjs';

export function ExitControls({ isHost }: { isHost: boolean }) {
const room = useMediasfuHeadless();
const [error, setError] = useState('');

async function leave(endRoomOnHostExit: boolean) {
const result = await room.controls.leave(false, endRoomOnHostExit);
if (!result.ok) return setError(result.error);
// Stop app-owned tracks and navigate only after success.
}

return <>
<button onClick={() => void leave(true)}>{isHost ? 'End room' : 'Leave'}</button>
{isHost && <button onClick={() => void leave(false)}>Leave and keep room open</button>}
{error && <p role="alert">{error}</p>}
</>;
}

Calling room.controls.leave() with no arguments uses the same true default.

Angular 2.3.1

async leaveAndKeepOpen() {
const result = await this.room.controls.leave(false, false);
this.error = result.ok ? '' : result.error;
}

async endRoom() {
const result = await this.room.controls.leave(false, true);
this.error = result.ok ? '' : result.error;
}

Keep MediasfuHeadlessService scoped to the room screen and dispose the screen only after the promise resolves.

Vue 1.1.1

const room = useMediasfuHeadless();

const leaveAndKeepOpen = () => room.controls.leave(false, false);
const endRoom = () => room.controls.leave(false, true);

Show result.error when ok is false and run router navigation afterward.

React Native 2.4.0

const room = useMediasfuHeadless();

async function leaveAndKeepOpen() {
const result = await room.controls.leave(false, false);
if (result.ok) navigation.goBack();
else setNotice(result.error);
}

Await track, renderer, and audio-route cleanup before destroying the room screen. A native back gesture should call the same semantic handler.

Expo 2.5.0

Use the React Native call from mediasfu-reactnative-expo. Verify it in a development build: Expo Go is not a substitute for native WebRTC teardown.

Flutter 2.3.0

final params = controller.parameters;
if (params == null) return;

final keepOpen = await leaveRoom(
params,
endRoomOnHostExit: false,
);
if (!keepOpen.ok) showError(keepOpen.error);

// The historical host-end path:
final end = await leaveRoom(params, endRoomOnHostExit: true);

The default is also true. Dispose the controller and app-owned tracks after the selected action completes.

Android and Kotlin Multiplatform 1.0.5

The current KMP headless controller exposes disconnect() but not a public endRoomOnHostExit option or semantic EndMeeting action. disconnect() alone must not be presented as host leave-without-ending or host end. Keep those two host controls unavailable in a fully headless Compose screen, or use a separately documented high-level room method whose contract you have verified in your installed version.

Swift and Apple platforms 0.1.3

The Apple package does not currently publish an independent Swift headless leave/end facade. Let the hosted MediaSFUIosHostBridge room own its supported exit flow. A Swift navigation dismissal is local UI cleanup, not proof that the room was preserved or ended.

Unity 0.1.0-preview.2

var leaveAndKeepOpen = await headless.LeaveRoomAsync(endRoomOnHostExit: false);
if (!leaveAndKeepOpen.Success) ShowError(leaveAndKeepOpen.Error);

var end = await headless.EndMeetingAsync(); // verifies host and active room
if (!end.Success) ShowError(end.Error);

LeaveRoomAsync() without the Boolean keeps the historical true default.

Shared core 1.1.0

import { leaveRoom } from 'mediasfu-shared';

const result = await leaveRoom({
parameters: latestParameters,
ban: false,
endRoomOnHostExit: false,
});

Consuming framework SDKs must still expose and bind this shared action; the shared export alone does not establish platform support.

Rejoin after preserving the room

  1. Await the host's preserve-room leave result.
  2. Remove the departed host's local tracks, renderers, and subscriptions.
  3. Keep the room identifier and application invitation authority server-side or in your authenticated session; do not retain a reusable Cloud credential.
  4. Run the normal join flow again with a fresh authorized join result.
  5. Wait for readiness and a current participant projection before restoring host controls.

If your application requires unique display names, wait for the old membership to clear before rejoining with the same name. Removing a participant prevents that current membership from remaining in the room; a durable account ban is an application/server policy unless the room contract explicitly binds identity beyond a user-chosen display name.

Reconnect is not rejoin

A transient socket interruption should use the SDK's reconnect lifecycle and retain the participant's original role. An intentional semantic leave creates a new join lifecycle. A host-ended room is terminal and should not display a reconnect button.

Teardown checklist

  • Label host End room and Leave and keep room open separately.
  • Await the chosen semantic action before navigation.
  • Stop app-created tracks and close superseded transports/renderers.
  • Ignore safe late acknowledgements from already closed state; surface other errors.
  • Clear room-scoped invitations and business state according to your application policy.
  • Test with a second participant: preserve, continue media, rejoin, then end.

Continue with media lifecycle, headless UI, and secure room authority.