WebsiteBeaver / CordovaCall

Cordova CallKit & ConnectionService plugin for iOS/Android that displays the native call UI for VOIP apps
MIT License
196 stars 91 forks source link

Not able to make network calls while device is locked #25

Closed HugoHeneault closed 6 years ago

HugoHeneault commented 6 years ago

I'm using latest https://github.com/phonegap/phonegap-plugin-push to get some VoIP notifications. It's running well when the phone is unlocked even when the app has been killed.

But when I lock the phone, I got the cordova-call screen showing, but on answer my socket.io is not able to connect.

I already opened an issue on the plugin push repo (https://github.com/phonegap/phonegap-plugin-push/issues/2245) but I think it's more related to CordovaCall than push plugin...

Did anyone get the calls working with webrtc while the screen is locked?

Here is a sample of my code:

pushObject.on('notification').subscribe(async (data: any) => {
    // even with app force closed, xcode shows this code in logs
    console.log("Push on notification", data);

    if (this.platform.is('ios')) {
         cordova.plugins.CordovaCall.receiveCall(data.additionalData.username);
    }
}

cordova.plugins.CordovaCall.on('answer', async () => {
     const socket = io(ENV.API_URL, {
          port: ENV.API_PORT,
          query: 'test'
     });

     socket.on('connected', () => {
          // this code never runs if the screen is locked
          // if we check in network tabs with safari open, we can see an infinite loading socket.io request
          console.log('connected');
     });
});

I need to create a socket.io connection to get ice and descriptions...

HugoHeneault commented 6 years ago

Maybe there is a way to force device unlocking before answering?

D-Marc1 commented 6 years ago

This is definitely not related to CordovaCall. PushKit was specifically made to allow VoIP apps to wake up the app and run code for a maximum of 30 seconds.

There's a few things I'm confused about your code. Why are you using async for cordova.plugins.CordovaCall.on('answer') and pushObject.on('notification') when there's no await? Why is socket.on('connected') nested inside of cordova.plugins.CordovaCall.on('answer')? As a rule of thumb, you shouldn't nest event handlers.

dmarcs commented 6 years ago

I agree with @D-Marc1. Your code should look like this

pushObject.on('notification').subscribe(async (data: any) => {
    // even with app force closed, xcode shows this code in logs
    console.log("Push on notification", data);

    if (this.platform.is('ios')) {
         cordova.plugins.CordovaCall.receiveCall(data.additionalData.username);
    }
}

const socket = io(ENV.API_URL, {
    port: ENV.API_PORT,
    query: 'test'
});

socket.on('connected', () => {
    // this code never runs if the screen is locked
    // if we check in network tabs with safari open, we can see an infinite loading socket.io request
    console.log('connected');
});

cordova.plugins.CordovaCall.on('answer', async () => {
});
HugoHeneault commented 6 years ago

So, some clarification (sorry guys my code might be misunderstood without context):

Even if I try to load something else than opening a socket (like load a 2ko json file), the connection is blocked. :(

If you have a way to make requests during the 30s after VoIP push notifications, I'd like to know what you're doing to get it working 🙂

D-Marc1 commented 6 years ago

I'd suggest using this plugin instead of PhoneGap Push for PushKit. Other than that, I'm sorry, but I'm honestly not sure what else to tell you. There's nothing special you need to do to make it work. I'd suggest trying to get PushKit to work first, and then worry about it integrating it with this plugin. The issue is likely how you're using Socket.io

dmarcs commented 6 years ago

I'm guessing that your code opens the socket connection too late. You probably need to open it earlier, and not in the callback.

HugoHeneault commented 6 years ago

So you're able to make connection requests going through network with pushkit on your side?

Because I'm using the latest https://github.com/phonegap/phonegap-plugin-push which handles VoIP notifications for iOS since https://github.com/phonegap/phonegap-plugin-push/pull/2194 has been merged... And pushkit seems to be working great (waking app even if it was locked, even with screen locked...)

I tried to open it at the exact moment when the VoIP notification arrives, but it's still not working :(

Thank you guys for your support!

dmarcs commented 6 years ago

I really think that you need to open the socket connection outside of onAnswer. You can check web inspector to see if your socket is connected. I have a demo video chat app that uses CordovaCall, the PushKit plugin that @D-Marc1 mentioned, iosRTC, and Firebase as the signaling server. It works perfectly even when the screen is locked and the app is closed. If I switch to Node.js, I'm sure it will still work.

Try making the socket connection when you first open the app, and let me know if that still doesn't work.

HugoHeneault commented 6 years ago

I'll try it and come back to you. I'm pretty sure I already tried opening the socket when the VoIP notification arrives. But I'll let you know.

Thanks for your tips.

dmarcs commented 6 years ago

@HugoHeneault Did you try opening the socket before the VOIP notification arrives? I would open the socket as soon as the app starts.

D-Marc1 commented 6 years ago

The guys at Socket.IO were nice enough to provide a nice tutorial on how to use it with Cordova. I know that you want to start the socket connection only when a user sends or receives a call, but I don't think that's possible, to my knowledge. You should start the socket connection as soon as you open the app.

HugoHeneault commented 6 years ago

The socket closes when the device is locked, after a few minutes. This is due to the way ios handles memory savings.

Coming back to my first question: did you guys manage to download content while receiving the VoIP notification? I don't think the issue is socket.io related, as I have the same issue if I try to make xhr requests or download content at the moment the notification is received...

D-Marc1 commented 6 years ago

This is without a doubt not a CordovaCall issue, as it's simply the native call UI and nothing more. You're combining CallKit, PushKit to wake up your app and using Socket.IO for your signaling server. I don't understand why you think it's related to this plugin at all.

HugoHeneault commented 6 years ago

I'm trying to get some intel from you because you seem to have a solution to make networks requests while your device is locked and CordovaCall shows up.

I don't get how I can make CordovaCall work if I'm not able to connect my socket to get my WebRTC working.

And you guys seem to have a working solution. I'm just trying to understand which one it is! 🙂

dmarcs commented 6 years ago

@HugoHeneault You could send any extra data via PushKit. You should only need to send the caller id and name with PushKit, but if you really need extra data just add it to the PushKit notification you send. There's no reason for you to use socket.io or an ajax call because like you said the socket gets closed when you turn off your phone, so you can't use it to reliably send data before the phone is ready.

I don't get how I can make CordovaCall work if I'm not able to connect my socket to get my WebRTC working.

You don't need sockets at all to get CordovaCall to work when the phone is off. You only need PushKit. I think that's the missing piece for you.

And you guys seem to have a working solution. I'm just trying to understand which one it is! 🙂

Yes I've created simple video chat apps several times using CordovaCall successfully. Once you realize that you shouldn't use socket.io to start CordovaCall, and that you should use PushKit instead of socket.io to send data, I think your app will work perfectly 🙂

HugoHeneault commented 6 years ago

Just a follow up for anyone having the same issues as me...

Everything was caused by WKWebview or https://github.com/ionic-team/cordova-plugin-ionic-webview. Removing it allowed me to open sockets, and make network calls even when the device was locked.

Thank you guys for insuring me it was working on your own so I could find what was wrong on my side. 🎉

It might be related to https://github.com/ionic-team/cordova-plugin-ionic-webview/pull/110 https://github.com/ionic-team/cordova-plugin-ionic-webview/pull/58 https://github.com/ionic-team/cordova-plugin-ionic-webview/pull/41