Reopening Created Subsessions not Working

Description
Today while testing I decided to run my old script that did three simple things, create one subsession, open the subsession, close the subsession, and then open it again. While testing, I had the issue that after closing the subsession the first time, it wouldn’t open again, but instead it made the browser tabs to freeze. When I closed the frozen tabs and tried the same sequence again, the same thing happened.

Browser Console Error
No errors.

Which Web Video SDK version?
1.9.5

Video SDK Code Snippets
Function to create subsessions

const createSubsessions = useCallback(
    async (subsessionNumber: number, pattern: SubsessionAllocationPattern) => {
      const totalParticipants = zmClient.getAllUser().filter(
        p => !p.displayName.endsWith('(Dozent:in)') &&
          !p.displayName.endsWith('(Moderator:in)')
      );

      if (totalParticipants.length < 1) {
        console.log('generated rooms', 0);
        message.info('Bitte versuchen Sie es erneut, wenn Teilnehmer verfügbar sind.');
        return;
      }
      message.info('Breakout-Räume werden erstellt. Bitte haben Sie etwas Geduld, da dies bis zu 10 Sekunden dauern kann. Wenn der Button nach 10 Sekunden nicht rot wird, klicken Sie bitte erneut.', 10);

      if (ssClient) {
        try {
          setRetryOpeningSubsessions(true);
          setIsRetryingOpenSubSessions(true);
          // const subsessions = await ssClient.createSubsessions(subsessionNumber, pattern);
          await ssClient.createSubsessions(subsessionNumber, pattern).then((subsessions) => {
            setSubsessions(subsessions as unknown as Subsession[]);
            openSubsessions();
          }).catch((err) => {
            if (err.reason === 'only host can do the operation') {
              message.error('Nur der Host kann den Vorgang ausführen');
            } else {
              message.error(err.reason)
            }
          });
        } catch (e) {
          console.warn(e);
        }
      }
    },
    [ssClient, setIsRetryingOpenSubSessions, openSubsessions, zmClient]
  );

Function to open subsessions


  const openSubsessions = useCallback(async () => {
    if (ssClient) {
      const guests = zmClient.getAllUser().filter(
        p => !p.displayName.endsWith('(Dozent:in)') &&
          !p.displayName.endsWith('(Moderator:in)')
      );

      if (guests.length < 1) {
        message.info(
          'Bitte versuchen Sie es erneut, wenn Teilnehmer verfügbar sind.'
        );
        return 0;
      }

      console.log('stored expected open room count', roomsToOpen)
      console.log('subsessions to open', subsessions);

      setRetryOpeningSubsessions(true);
      setIsRetryingOpenSubSessions(true);

      if (!subsessions.length || !ssClient.getSubsessionList().length) {
        return;
      }

      try {
        await ssClient.openSubsessions(subsessions, options).then(() => {
          setSubsessionStatus(() => SubsessionStatus.InProgress);

          if (ssClient.getSubsessionStatus() === SubsessionStatus.InProgress) {

            if (unassignedUserList.length) {
              const randomSubSession = subsessions[Math.floor(Math.random() * subsessions.length)];
              let participant: Participant | null;
              unassignedUserList.forEach(async (user) => {
                participant = user;
                ssClient.assignUserToSubsession(
                  user.userId,
                  randomSubSession.subsessionId
                ).then(() => {
                  setSubsessions(
                    produce((subsessions: Subsession[]) => {
                      const subsession = subsessions.find((r: Subsession) => r.subsessionId === randomSubSession.subsessionId);
                      if (subsession && participant) {
                        subsession.userList.push({
                          userId: participant.userId,
                          displayName: participant.displayName,
                          avatar: participant.avatar,
                          isInSubsession: true
                        });
                      }
                    })
                  );
                });
              });
            }

            if (chatClient && chatClient.getPrivilege() === ChatPrivilege.NoOne) {
              chatClient?.setPrivilege(ChatPrivilege.EveryonePublicly).then(() => {
                message.info('Die Chat-Berechtigung "Alle dürfen sprechen" wurde wieder aktiviert, um sicherzustellen, dass die Nutzer in den Breakout-Räumen schreiben können.');

                setAllowChatting(true);
              });
            }

            if (guests.length) {
              guests.forEach(async (g) => {
                await mediaStream?.unmuteAudio(g.userId);
                console.log('muted', g);
              });

              setUnmuteAllParticipants(true);
              setCurrentQueue((currentQueue: HandQueue[]) => []);
            }

            setDoNotDisturb(false);
            const moderator = zmClient.getAllUser().filter((u) => u.displayName.endsWith('(Moderator:in)'));
            if (moderator.length) {
              let command = {
                action: 'sent-moderation-update',
                dnd: false,
              }

              cmdClient?.send(JSON.stringify(command), moderator[0].userId);
            }
          }

        }).catch((err) => {
          if (err.reason === 'only host can do the operation') {
            message.error('Nur der Host kann den Vorgang ausführen');
          } else {
            message.error(err.reason)
          }
        });

      } catch (err) {
        console.log(err);
      }

      setRetryOpeningSubsessions(false);
      setIsRetryingOpenSubSessions(false);
      // await assignUnassignedUsersToAnyRunningSubsessions();
      console.log('sub open status', subsessionStatus);
      console.log('ssclient stat', ssClient.getSubsessionStatus());
    }
  }, [
    ssClient,
    zmClient,
    setIsRetryingOpenSubSessions,
    subsessionStatus,
    subsessions,
    unassignedUserList,
    roomsToOpen,
    options,
    chatClient,
    setDoNotDisturb,
    setAllowChatting,
    setUnmuteAllParticipants,
    setCurrentQueue,
    mediaStream,
    cmdClient
  ]);

Function to close subsessions


  const closeAllSubSessions = useCallback(async () => {
    if (ssClient) {
      setRetryOpeningSubsessions(false);
      await ssClient.closeAllSubsessions()
        .then(async () => {
          if (ssClient.getSubsessionStatus() === SubsessionStatus.Closed) {

            const guests = zmClient.getAllUser().filter(
              p => !p.displayName.endsWith('(Dozent:in)') &&
                !p.displayName.endsWith('(Moderator:in)')
            );

            if (guests.length) {
              guests.forEach(async (g) => {
                await mediaStream?.muteAudio(g.userId);
                console.log('muted', g);

                let command = {
                  action: 'host-ask-mute',
                  sender: zmClient.getSessionHost()?.userId
                }

                cmdClient?.send(JSON.stringify(command), g.userId);
              });
            }

            setUnmuteAllParticipants(false);

            await chatClient?.setPrivilege(ChatPrivilege.NoOne);
            setAllowChatting(false);

            setDoNotDisturb(true);
          }
        })
        .catch((err) => {
          if (err.reason === 'only host can do the operation') {
            message.error('Nur der Host kann den Vorgang ausführen');
          } else {
            message.error(err.reason)
          }
        });

      console.log('Done');
      console.log('retry-subs', retryOpeningSubsessions);
    }
  }, [
    ssClient,
    retryOpeningSubsessions,
    zmClient,
    setUnmuteAllParticipants,
    chatClient,
    setAllowChatting,
    setDoNotDisturb,
    mediaStream,
    cmdClient
  ]);

To Reproduce(If applicable)
Steps to reproduce the behavior:

  1. Create subsession and open subsessions
  2. Close subsessions
  3. Try to open subsessions again.
  4. See error

Hey @godwin.owonam,
I can double check but I believe if you’ve closed all subsessions, you’ll first have to create them again and then open them after. Have you tried that?

Thanks @ekaansh.zoom

Well, closing subsessions does not “remove” the subsessions. It just returns the participants to the main room and marks the subsession as closed. You can reopen the same subsessions.

The main issue here is that the ssClient.closeAllSubsessions() method resolves and does not put the subsessions in “Closed” state, but in “Closing” state. So when I fire another event when this is resolved, it puts the subsessions in an unknown state. So when I try to reopen the subsessions or create new ones, my browser just freezes.

In the snippet below

ssClient.closeAllSubsessions().then(async() => {
    await chatClient?.setPrivilege(ChatPrivilege.NoOne);
     setAllowChatting(false);
});

would cause the subsessions to freeze my browser after closing if I try to reopen or recreate the subsessions.

If I put a check to ensure that the subsessions are closed before executing the code above,

ssClient.closeAllSubsessions().then(async() => {
    if (ssClient.getSubsessionStatus() === SubsessionStatus.Closed) {
        await chatClient?.setPrivilege(ChatPrivilege.NoOne);
        setAllowChatting(false);
     }
});

then the code between the ‘if’ clause does not run.

Hey @godwin.owonam

I apologize for the documentation not clearly explaining the changes in subsession status.

After calling ssClient.closeAllSubsessions(), the subsession’s status becomes SubsessionStatus.Closing.

This is because if there is a waitSeconds option in ssClient.openSubsessions, it is intended to wait for users still in the subsession to leave. So, when ssClient.closeAllSubsessions() is called, the subsession’s status changes from SubsessionStatus.InProgress to SubsessionStatus.Closing and finally to SubsessionStatus.Closed .

You can monitor this state change by listening to the subsession-state-change event.

Thanks
Vic

1 Like

I guess you mean event_bo_room_state_change on the event-callbacks.

Thanks. I will let you know when I try this solution.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.