Skip to main content
Version: 3.x.x

Waiting Lobby - Android

Overview​

A waiting lobby lets the host decide who joins the room. A guest asks to join, and the host allows or denies the request. The steps are below.

Generating Tokens in Your Backend​

Your server should generate access tokens using your API key and secret. Two different tokens need to be generated with different permissions:

HOST Token Payload​

{
// ...
apikey: API_KEY, // Your API key
permissions: ['allow_join'], // Permission to directly join the room
// ...
}

GUEST Token Payload​

{
// ...
apikey: API_KEY, // Your API key
permissions: ['ask_join'], // Permission to ask the host for permission to join the room
// ...
}

Explanation of parameters:

  • apikey (Mandatory): Your API key generated from the VideoSDK Dashboard, which can be obtained here.

  • permissions (Mandatory): Permissions that control participant activity. Available permissions include:

    • allow_join: Participants are allowed to join the room directly.
    • ask_join: Participants need to ask for permission to join the room. Participants with the allow_join permission can accept or reject others' join requests.
    • allow_mod: Participants are allowed to toggle webcam and mic of other participants.

Then, sign this payload with your SECRET KEY and use the HS256 algorithm. For more details on authentication and tokens, refer to this guide.

Generating Room ID​

With the tokens ready, you can now obtain the roomId from the VideoSDK's rooms API, which can be found here.

Refer to this guide for generating the roomId.

Initializing the Room​

Create the room with VideoSDK.createRoom() and pass the token to it. The token decides whether the participant joins the room directly or waits in the lobby, so provide the allow_join token to a host and the ask_join token to a guest.

Also pass a participantId. A guest needs it to recognize the answer to its own request: until the guest is let in, room.localParticipant.id is the participantId you passed, or empty if you passed none.

For detailed configuration options, check here.

// If a participant joins as a host, provide them with the "allow_join" permission token.
// Otherwise, provide the "ask_join" permission token.
val token = if (isHost) "allow_join token will be here" else "ask_join token will be here"

room = VideoSDK.createRoom(
roomId = roomId,
token = token,
participantName = "NAME HERE",
micEnabled = true,
camEnabled = true,
participantId = participantId, // a unique id for this participant
multiStream = false,
)

room!!.addEventListener(roomEventListener)
lifecycleScope.launch {
try {
room!!.join()
} catch (e: VideoSDKException) {
Log.e("VideoSDK", "Join failed: ${e.code} ${e.name}")
}
}
note

A participant joining with the ask_join token does not enter the room when join() is called. The onRoomJoined event is emitted only after the host allows the request, and until then the guest's join() call keeps waiting.

Events associated with Waiting Lobby​

The following events are received when a participant tries to join the room.

  • When a participant joins as a host, they will receive an onEntryRequested event whenever a guest participant tries to join the room. It carries the guest's participantId, their name, and two functions: call allow() to let the guest in, or deny() to turn them away. Nothing happens until you answer; an unanswered request waits until the server times it out.

  • You can also answer later with respondEntry(participantId, decision). It is a suspend function, so call it from a coroutine. Pass EntryDecision.ALLOWED or EntryDecision.DENIED as the decision.

  • An answer given after the room was left, or while it is reconnecting, is not sent, and the reason is reported on onError.

  • When the host responds to a request, both the host and the guest will receive an onEntryResponded event with the participantId of the guest and a decision of either EntryDecision.ALLOWED or EntryDecision.DENIED.

private val roomEventListener: RoomEventListener = object : RoomEventListener() {
override fun onEntryRequested(
participantId: String,
name: String,
allow: () -> Unit,
deny: () -> Unit,
) {
// The host receives this event when a guest requests to join the room
// If you want to allow the entry request
allow()

// If you want to deny the entry request
// deny()
}

override fun onEntryResponded(participantId: String, decision: EntryDecision?) {
// participantId is the ID of the participant who requested to join the room
if (participantId == room!!.localParticipant.id) {
// This is the response to your own request to join
if (decision == EntryDecision.DENIED) {
// Leave the room and navigate away from the room screen
lifecycleScope.launch {
try {
room!!.leave()
} catch (e: VideoSDKException) {
Log.w("VideoSDK", "Leave refused: ${e.code} ${e.name}")
}
}
}
return
}

// The response is for a guest's request
if (decision == EntryDecision.ALLOWED) {
// Entry allowed
} else {
// Entry denied
}
}
}
note

onEntryResponded is emitted to every participant whose token includes the allow_join permission and to the participant who requested to join, including a participant receiving their own participantId with a decision of EntryDecision.ALLOWED. Check the participantId and the decision before treating this event as a response to a guest's request.

caution

A guest whose request is denied is not disconnected from the room automatically. Call leave() on the guest and navigate away from the room screen when the decision is EntryDecision.DENIED. If the guest's join() call is still waiting, leave() cancels it, and join() throws VideoSDKException with code 3056 (ERROR_OPERATION_ABORTED).

API Reference​

The API references for all the methods and events utilized in this guide are provided below.

Got a Question? Ask us on discord