cordova-rtc/cordova-plugin-iosrtc

Crash when calling any plugin function within a WebSocket event

ibc opened this issue · 20 comments

ibc commented

Reported in the Cordova project: https://issues.apache.org/jira/browse/CB-9102

ibc commented

This is properly explained in the README and a working workaround is provided. Closing this issue since nothing can be done here (it is a iOS Safari or a Cordova bug).

ibc commented

I will reopen this issue just for people to be aware of the problem.

This issue is still reproduced on iOS 7.1

ibc commented

And also in iOS 8.3, the latest one.

I mean it's still reproduced in iOS 7.1 with ios-websocket-hack.js. And it works fine with your hack in the iOS version higher than 8.0.

ibc commented

Interesting. May you please comment that in the issue I reported in the Cordova tracker? I got zero feedback in there...

Could you tell me the iOS hardware version you are using, 32bit or 64bit? After testing on different HWs, I find crash happens on 64bit hardware.

ibc commented

I've tested in iPad Mini 64 bits and also in the iPhone Simulator in OSX (not sure whether that is 32 or 64 bits, I would say that it is 32 bits...).

I getting random WebThread crashes with EXC_BAD_ACCESS only when running on device (doesn't happen with simulator or Chrome).
Usually in:
JavaScriptCoreJSC::JSObject::getOwnPropertyNames`

I don't directly access any cordova plugins in my code,
but I use socket.io-client, maybe it does.

I tried the suggested workaround and the crash still happens.
(I verified that the ios-websocket-hack.js actually runs)

Could it still be related to this issue?
How can I debug it and get more info? (I just see the assembler like crash log in Xcode)

Thanks for any idea,
Erez

I am using :

Cordova 6.3.0
cordova-plugin-iosrtc 3.1.0 (just for trying out workaround)
Xcode 7.2.1
npm 3.10.3
node 6.3.0
socket.io-client 1.4.0
Device is: iPad 2 with iOS 8.3

ibc commented

Honestly no idea.

I noticed that since iOS 10, the WebSocket hack causes problems in my Meteor application. To be more precise, it prevents my users from logging into my app. I first thought this was due to a bug in iOS 10 itself, but eventually I found out that my login problems go away once I disable this hack. Also, the hack slows down the app performance notably, since Meteor heavily relies on WebSockets.

So I am looking for a solution to only enable the iOS hack if it is really needed, i.e. during a WebRTC session. My first attempt was to override the WebSocket constructor only before a session takes place and restore it afterwards. But this did not work reliably, as some of the WebSockets were instantiated before I started WebRTC calls.

Hence, I need a more fine-granular approach that enables and disables the "setTimeout" calls as required.

@ibc Could you please tell me which of all these setTimeout calls are really required for to prevent the app from crashing? There's a lot of them in the code. I'm especially wondering why all event handlers (like self.ws.onopen) are wrapped with setTimeout(), since they only call dispatchEvent() which itself executes its event handlers inside another setTimeout(). Are these nested setTimeouts() really necessary? I'm also wondering why even the constructor is called inside a setTimeout().

Thanks in advance for your help.

ibc commented

but eventually I found out that my login problems go away once I disable this hack

Does the app crash without it? maybe something changed in iOS 10.

Could you please tell me which of all these setTimeout calls are really required for to prevent the app from crashing?

The crash just happens when invoking plugin calls within a WebSocket event. If you hack it by calling a setTimeout() to run such a call, then the call is called from a later JS iteration and the crash does not happen. That's the reason to be of the hack.

However, I don't know if the iOS cordova app just crashes when calling a iosrtc call within a WebSocket event, there is no enough info about that.

Hey, thanks a lot for responding on a Sunday evening, highly appreciated!

Does the app crash without it? maybe something changed in iOS 10.

Not sure, as I am also facing #242 now. I first thought this was related to me disabling the hack completely, but now I learned that it's actually a different problem.

The crash just happens when invoking plugin calls within a WebSocket event. If you hack it by calling a setTimeout() to run such a call, then the call is called from a later JS iteration and the crash does not happen. That's the reason to be of the hack.

Yes, that's how I understood it. I was wondering if all of these setTimeouts() in the hack are actually needed. It seemed as if some were nested.

Closing, this is a known problem in iOS, which the documentation already points out, including a workaround, there is nothing actionable.

Hi guys,

First, thanks for the amazing work you're providing with this plugin.

As of today, on iOS 10.2.1, I can make my clone of "AppRTC" work without the websocket hook (ios-websocket-hack.js). Which is great, because I noticed that when using it, on both Android [1] and iOS, my clone of AppRTC was not working as good as it should.
For instance, if my addressee (using Chrome for desktop) gets into the "room" after me (using an iPhone 5, iOS 10.2.1, cordova-ios 4.3.1), he won't see/receive my video stream. If he joins the room before me, he can see my video stream.

I know it could be the fault of my AppRTC clone, but just in case, did you guys ever noticed something similar or any strange behavior using this hook?
(Additionally, do you know from which iOS version we can get rid of it? On my iPhone 5@iOS 10.2.1, it works fine without it, as a direct peer and through a TURN server).

[1]: I also tested it on Android by changing its source code, in order not to be blocked by the test window.device.platform === 'ios'

Thanks again
Regards

NB: I wanted to fill a new issue but I feel like this one is perfect to share these details. What do you think?

ibc commented

do you know from which iOS version we can get rid of it (the ios-websocket-hack.js)?

No idea, have you read about any fix in iOS safari about it?

NB: I wanted to fill a new issue but I feel like this one is perfect to share these details. What do you think?

Definitely report here updates/changes to the issue original subject.

Hi @ibc, pleased to talk to you.

I just tested my clone of iOSRTCApp without the ios-websocket-hack, on an iPad 2 @ iOS 9.2, and I couldn't make it crash. I made sure I was using a different network, so the TURN servers are, by the way, implied in the communication. It also worked well on the same network (video + sound).

I'm trying to make it work on the iOS simulator to see if I can find from which version it starts crashing... Maybe all versions of iOS 8, and fixed from iOS 9?... More to come soon. BTW, if you're still interested in iOSRTCApp, my fork is using the last version of Swift, the last version of apprtc, and the last version of the iosrtc plugin. I also made some refactoring regarding the app initialization (code moved from appwindow.html to init.js).

EDIT - Couldn't make it crash on the iOS simulator either... Simulated: iPad 2 @ iOS 8.1. Do you think it's because of the simulator? Or iOS 8.1 doesn't have the issue? I'd like to find a version of iOS where I can reproduce this.

ibc commented

Honestly no idea (I don't have an iOS device to test). However, for sure, the crash did happen with iOS 8.3 (commented above in some old comment).

Yup you're right, I completely forgot to read again the previous comments.

only when running on device (doesn't happen with simulator or Chrome).

Indeed, it seems that the simulator is not trustable.

Well, in that case, I can confirm that it's working on real devices using iOS 9.2 and 10.2... I need to find an easy/quick way to try real devices on iOS 9.0 and 9.1... But maybe I didn't try for a time long enough to provok a crash...

Thanks anyway. Will keep you posted if I find out when (which version) the issue has been addressed by Apple.