Manually leave the meeting in case internet lost

[I’m using custom UI]
I notice that when i tried to turn off wifi connection, the connection is not really ended, the SDK trying to reconnect and keep the call alive and after several reconnect times, the onDestroyMeetingView is called and my custom UI is dismissed (as I handle dismiss the call window at this delegate; and in this function, i just destroy my window without calling leaveMeeting(with: .leave) ).

And after that, i turn on wifi connection, then the call session become alive and i still send my audio & video session to the participants (i dont see my local video since i dismissed my call window in the above step).

My questions is: How can i leave the meeting in case internet lost (as the case i mentioned) or is there any suggestions for handling these kinds of cases.

Thank you so much.

Hey @zacob,

Thanks for using the dev forum!

After the meeting is reconnected, the onInitMeetingView should be triggered again. Can you check if that is happening for you?

Thanks!
Michael

This is the problem that i’m facing. Because before meeting is reconnected, the onDestroyMeetingView is triggered; and at this step, i dismissed my custom call UI (and also cleared my additional data like call info, users…)

Is there any way for me to turn off the reconnect mechanism? Since for my app, i want to dismiss the call UI right after internet lost and dont need to auto connect again.

Hey @zacob,

There is not a way to disable the reconnecting state. You could keep track of when the meeting has had an ended state, and then only dismiss your UI in the onDestroyMeetingView callback if the meeting has had an ended state.

Thanks!
Michael

Thank you @Michael_Condon . Let’s me try your way.

Sounds good! Let me know what happens.

Thanks!
Michael

Hi @Michael_Condon, as your guidance, it works for me when i only dismiss my custom UI in onDestroyMeetingView only if the current state of the meeting is ended.

However, i have one more issue since i call leaveMeeting(with: .leave) in this function (i named it leaveCurrentCall).In case it’s called when i click the button Leave in my UI and still have internet → it works well; after leave i still can join the meeting.

But in case internet lost, i click Leave → dismiss my UI → call leaveMeeting(with: .leave). Then once internet gets back, i join meeting as usual (with meetingService.joinMeeting(with: joinMeetingParameters)), then nothing happens, none of MobileRTCMeetingServiceDelegate is called and onInitMeetingView neither.

Could you please help me on this? Thank you.

Hey @zacob,

Is it possible that your MobileRTCMeetingServiceDelegate became nil in transitioning from the meeting?

Thanks!
Michael

Thanks @Michael_Condon
To make it safe, i set MobileRTC.shared().getMeetingService()?.delegate = self in my onDestroyMeetingView & right before meetingService.joinMeeting(with: joinMeetingParameters)
What do you mean about ‘in transitioning from the meeting?’, could you give me a clue. In the meantime, i am going to check where my delegate can be nil.

Hey @zacob,

So in my own application, I have the custom meeting UI controlled by a viewcontroller called CustomMeetingUIViewController. My main ViewController both a CustomMeetingUIDelegate and a meetingServiceDelegate. When onInitMeetingView is called, I create a CustomMeetingUIViewController, and assign the CustomMeetingUIViewController to be the meetingServiceDelegate instead. Then when onDestroyMeetingView is called I re-assign the main ViewController to be the meetingServiceDelegate.

You may have yours set up in a different way, but I am curious if when you leave the meeting and destroy your UI that the meetingServiceDelegate is now nil.

Thanks!
Michael

Hi @Michael_Condon , i have the almost same way with a little difference.

I have a class called MeetingManager to handle setupSDK, authenticate, etc. And a CustomMeetingUIViewController like yours.

When onInitMeetingView is called, i create CustomMeetingUIViewController but still assign MeetingManager to be the meetingServiceDelegate.

When the internet is lost, when i destroy my custom UI without calling .leave, my audio and video stream still alive in the other participant (my case is 1-1 call). So that why i have to call .leave, but this time the internet is lost and i am not sure that the .leave command is executed.

Could you please reveal more about the ‘My main ViewController’?

Hi @Michael_Condon
I made some change in my onDestroyMeetingView like this:

MobileRTC.shared().getMeetingService()?.delegate = self
if MobileRTC.shared().getMeetingService()?.getMeetingState() == .ended {
    self.dismissCallWindow()
}

Made some debugs and see that, after i connect internet again, my serviceDelegate is not nil. And my problem is that the meeting state (i re-join the same room) change as following:

  • Disconnecting - Disconnect the meeting server, leave meeting status.
  • Connecting - Connect to the meeting server status.
  • Ended - Meeting ends.

Any suggestions for a good way to handle this case? Thank you Michael.

Hi @Michael_Condon

I have investigated for a couple of times, after i call joinMeeting(with: joinMeetingParameters) , my meetingServiceDelegate still not nil but none of function in delegate is called.

Below is what i printed out after call join meeting and wait for callbacks from delegate.

Could you please help on what i need to check for more investigation?
Thanks.

Hey @zacob,

I see, let me run some tests right now and I will let you know what I find.

Thanks!
Michael

Hey @zacob,

I think I see what is going on here. Calling the leave function while the internet is disconnected does not appear to execute the leave process since it has to alert the meeting the user has left.

Here is a workaround that worked for me:
Implement the onMeetingStateChange delegate callback:

func onMeetingStateChange(_ state: MobileRTCMeetingState) {
        if state == .ended && leftWaitingRoom == false {
            leftWaitingRoom = true
        } else if state == .ended && leftWaitingRoom == true {
            hasReconnected = true
        }
    }

Keep track of when the meeting state was .ended with a boolean, hasReconnected. Keep in mind when the user is admitted from the waiting room, the state will be .ended. So we are looking for the second time the state was .ended when using a waiting room. That is why I also have a “leftwaitingroom” boolean

In your onInitMeetingView method check if has reconnected is true, if so do not recreate your UI and call leave just for safety:

func onInitMeetingView() {
        if hasReconnected == true {
            MobileRTC.shared().getMeetingService()?.leaveMeeting(with: .leave)
            return
        }
        
        guard let customMeetingUIVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "CustomMeetingUIViewController") as? CustomMeetingUIViewController,
              let meetingService = MobileRTC.shared().getMeetingService() else { return }
        meetingService.delegate = customMeetingUIVC

        self.present(customMeetingUIVC, animated: false, completion: nil)
        self.customMeetingUIViewController = customMeetingUIVC
        updateViews()
    }

Then in your onDestroyMeetingUI simply dismiss your UI as usual:

    func onDestroyMeetingView() {
        MobileRTC.shared().getMeetingService()?.delegate = self
        updateViews()
        return
    }

Finally when calling joinMeeting set your hasReconnected bool back to false.

This seemed to work for me, when the user disconnects the UI is dismissed, then the .ended state happens, and we do not re-show our UI. After some time the user is automatically removed from the meeting and then the joinMeeting function can happen again.

Its a bit of a hacky solution, but this is not normally a use-case Zoom handles.

Thanks!
Michael

1 Like

Hi Michael, highly appreciate your support.

I tried to put some details logs and let me clarify some points:

  • [1] In normal case leave when internet ON, the state sequence is: Disconnect → On Destroy Meeting View is called → Connecting → Ended.

  • [2] In case leave when internet OFF, the state sequence is:
    Disconnect → On Destroy Meeting View is called → Connecting → Ended. (The same as [1]).
    After that, i see the SDK will reconnect by trying to do the same steps as when i call joinMeeting(with: joinMeetingParameters)
    Join meeting confirmed → On Init Meeting View → Connecting → Throw MobileRTCMeetError network issue, please check network connection → On Destroy Meeting View → Disconnecting → Failed → Connecting → Ended

And combine with what you provided me, the way is determine the second time meeting state changed to Ended (after SDK tried to reconnect by failed) (as your hasReconnected purpose)

After getting hasReconnected, and internet gets back to ON, in the next call of onInitMeetingView, it’s the time to call leave as you mentioned, to notify to Zoom server that now we leave the meeting (Because the .leave only executed with internet ON)

func onInitMeetingView() {
        if hasReconnected == true {
            MobileRTC.shared().getMeetingService()?.leaveMeeting(with: .leave)
            return
        }
.....
}

I wonder that this onInitMeetingView call is automatically by Zoom. Because when internet on, my custom UI might be dismissed and i haven’t called joinMeeting (by press Join button from my application). If yes, there’s can be a case that i call joinMeeting while hasReconnected still be true and i need to wait for awhile to wait joinMeeting happens again, is it right?

Really appreciate that you spent time for my questions. Thank you @Michael_Condon .

Hey @zacob,

Yes I believe that the onInitMeetingView will be called automatically again regardless of internet connection. I see your point, that the internet can still be disconnected when attempting to call leave meeting in this scenario. Try leaving the hasReconnected == true if statement in the onInitMeetingView but only return in this case. And then move the leave call inside of the onMeetingStateChange call. You might have to monitor the order of states to see when this would apply, but if you can detect when the SDK notices the internet comes back inside of the onMeetingStateChange callback, you could call:

if hasReconnected == true {
     MobileRTC.shared().getMeetingService()?.leaveMeeting(with: .leave)
}

there instead.

Michael

Basically, onMeetingStateChange is going to be the only reliable place to monitor the state of the meeting connection. So that is probably actually where this logic needs to be

Thank you for your support, @Michael_Condon ,
Is there anyway in Zoom SDK that allow we keep track the internet connection state? Or monitoring the meeting state is the only way to do that for now?
I’m going to try what we discussed to my app to handle the internet lost case today and will let you know what happens.
Thanks.

Hi @Michael_Condon
Your suggestion worked fine for my case.
After that, i extended my use-case to other scenarios with internet connection and found another way to handle.
I created a network monitoring to keep track the network state sequence (on/off). Every time the state changed from Off to On, i use MobileRTCInviteHelper.sharedInstance().ongoingMeetingNumber to check if there’s any ongoingMeetingNumber (may be leave command is called when internet is off) and my call window is dismissed before, then i will call MobileRTC.shared().getMeetingService()?.leaveMeeting(with: .leave)

To make sure Zoom refresh and make joinMeeting happens again, i locked my UI for awhile (1-2 seconds) with a progress loading after the leave command sent to Zoom (I am not sure if it’s necessary, since i think Zoom will take a little bit of time to execute the leave before get ready for the new joinMeeting).

And thank you for your great support @Michael_Condon