Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on disconnect between iOS server and Android client #20

Closed
bugnano opened this issue Dec 15, 2016 · 20 comments
Closed

Crash on disconnect between iOS server and Android client #20

bugnano opened this issue Dec 15, 2016 · 20 comments

Comments

@bugnano
Copy link
Contributor

bugnano commented Dec 15, 2016

The situation is the following:
Server: iOS cordova-plugin-websocket-server version 1.3.0
Client: Android Crosswalk version 21 (based on Chromium version 51), native WebSocket client.

The connection is made correctly, the data is sent and received correctly on both ends, but when the client disconnects (by calling connection.close() without arguments), the server crashes.

The strange part is that the server does not crash if both the server and the client are iOS (unless there was an error in my iOS to iOS testing...).

Also, as I use this plugin to implement a real-time multiplayer game, I have found a latency issue that only affects iOS (when testing both server and client on Android, the ping is around 6mS, when either the server or the client, or both run iOS, the ping is much higher, and varies continuously between 20mS and 500mS). Any idea on why this latency problem related to iOS happens?

@bugnano
Copy link
Contributor Author

bugnano commented Dec 15, 2016

The same crash occurs also when listening for a connection, and closing the server (by calling wsserver.stop()) before a client connects.

XCode breaks on a disassembly, but from the stack trace, it seems that the crash occurs when calling

[PSWebSocketServer dealloc]

@becvert
Copy link
Owner

becvert commented Dec 15, 2016

could it be related to couchbase#1369

About the latency, to be sure, can you confirm that:
1- Android client + Android Server is OK?
2- Android client + iOS server is bad?
3- iOS client + Android server is bad?
4- iOS client + iOS server is bad?

@bugnano
Copy link
Contributor Author

bugnano commented Dec 15, 2016

I don't have much expertise with XCode, so I don't know whether my stack trace is comparable to the issue you mentioned or not.

To quickly reproduce this issue you can set up a server on iOS, and then close it before making any connection (I'm using XCode 8.2, the latest version of Cordova and related plugins) on an iOS 10.2 device (iPad Air).

Unfortunately I confirm the latency situation. I was sincerely hoping that it was a server-only issue also here, but also an Android server with an iOS client has latency problems (maybe there are some special considerations in order to make WebSockets fast on iOS?).

The only other person that reports a similar problem to mine is this one:

http://stackoverflow.com/questions/8793823/ios-safari-websockets-huge-latency-when-sending-messages-at-short-intervals

As I'm using this plugin in a real-time multiplayer game, both the client and the server send asynchronously messages at 33 or 50mS intervals.

According to the StackOverflow answer that I linked earlier, it seems that the latency problem disappears if the server responds to every message sent by the client, but I haven't tried it yet (and I'm reluctant to change my code like that, as it will increase the network traffic and maybe make the situation worse. Moreover this would fix only the iOS client side, and not the iOS server side).

@becvert
Copy link
Owner

becvert commented Dec 15, 2016

I opened #21 to discuss latency.

I'll investigate the crashes issue but not before a few days probably.

@becvert
Copy link
Owner

becvert commented Jan 3, 2017

@bugnano does the problem still occur?
I'm not able to reproduce it right now.

@bugnano
Copy link
Contributor Author

bugnano commented Jan 4, 2017

The problem still occurs, unfortunately.

In order to reproduce this problem, I'm calling wsserver.start() with port number 0, and as a second argument I specify the onStart, onDidNotStart, onOpen, onMessage and onClose callbacks.

After a few seconds, I decide to disconnect, and in order to do so I do the following:

For every connected client, I call wsserver.close() with the exact same conn object returned by the onOpen callback.

Lastly, I call the wsserver.stop() function with no parameters, and here is when the crash occurs.

The crash happens every single time, regardless whether there were connected clients or not.

@becvert
Copy link
Owner

becvert commented Jan 6, 2017

OK I believe you.
But I'm unable to reproduce the problem.
I tested an app from scratch with just this plugin; connected from Chrome, Safari and XWalk with pure websocket clients; I followed your steps. But the iOS server does not crash.
My apps in production behave fine. I do not have report from users yet.

I propose that you update your XWalk version, and that you make sure to clean properly your xcode build, and re-install that plugin. Maybe test a new sample app with just this plugin too.

For the time being I'll leave you with that problem, sorry, until me or someone else come across the same issue.

@bugnano
Copy link
Contributor Author

bugnano commented Jan 10, 2017

I think I've managed to work around this crash in the following way:

What I forgot to mention is that my app calls wsserver.stop() right before calling wsserver.start(), in order to be sure that we start from a clean condition.

I suspect that on the native side of the plugin, stopping a server that was not created before, instead of being a no-op, would cause a situation that crashes once a server gets created, and then disconnected.

I worked around this crash by doing 2 things:

  1. I Call wsserver.stop() only if there was a call to wsserver.start() beforehand
  2. The wsserver.start() call is delayed 50ms after the wsserver.stop() call

I really do not like a workaround like this one, but in order to have a clean situation I propose to check 2 things in this plugin, please:

First of all, can you check on the native part of the plugin (especially on iOS, but it won't hurt to check also Android, just to be sure) that it is safe to call wsserver.stop() anytime, and if there is no server running, this call behaves just like a no-op, please?

The second thing is that I would like to modify the JS interface, in order to have a success (and possibly a failure callback) for the wsserver.close() and wsserver.stop() functions. This would allow to start a new server after we are sure that the previous instance has been successfully closed (if any), with code like this:

wsserver.stop(function () { /* Now we are sure that there is no server running */ wsserver.start(); });

instead of using a setTimeout() and hoping that the previous instance has been closed by then.

Can you make these modifications, please?

@becvert
Copy link
Owner

becvert commented Jan 11, 2017

OK. give me a week or two before I can see what I can do about that. Thanks.

@becvert
Copy link
Owner

becvert commented Jan 24, 2017

Hello, I've made some changes.
Could you test branch 1.4.0 please? and tell me what you think?

@bugnano
Copy link
Contributor Author

bugnano commented Jan 24, 2017

Sorry for the noob question, but how do I install the plugin from branch 1.4.0?

I tried with the command:

cordova plugin add https://github.com/becvert/cordova-plugin-websocket-server/tree/1.4.0

but it fails with the error: Repository not found

@becvert
Copy link
Owner

becvert commented Jan 24, 2017

Can you clone the repo and switch to the branch?
then install from the local system
cordova plugin add ../path/to/my/plugin

@bugnano
Copy link
Contributor Author

bugnano commented Jan 24, 2017

I found 2 problems with this branch.

The first one is the easiest to fix, and I fixed it with pull request #24

The second one is that unfortunately, the server still crashes on the [PSWebSocketServer dealloc] function, so, while I like the new API, unfortunately this issue still remains.

@becvert
Copy link
Owner

becvert commented Jan 24, 2017

Thanks for the PR and your feedback.
I can't seem to reproduce the crash on dealloc.
Have you tried to run your code in the xcode simulator or on another device by any chance?
Have you got any special debugging option enabled that would break on dealloc and that I wouldn't have on my side?

@bugnano
Copy link
Contributor Author

bugnano commented Jan 24, 2017

I didn't run the code in the simulator, as I already found out on a different occasion that code that works perfectly fine in the simulator will not run on a real device, so I prefer to always test on a real device.

As I'm not that good with the Mac (I'm mostly a Linux guy...), I left all the XCode configuration options to their default values. I try to keep both the development environment (XCode, Cordova, etc...) to their latest stable version, as well as the OS on the devices (an iPad Air and an iPhone 5S) to their latest version.

@becvert
Copy link
Owner

becvert commented Jan 25, 2017

Does the crash occur every time or is it random?

iOS has received an update yesterday, so it's maybe woth shot.

By the way, I don't think you have to close all connections before stopping the server,
as it should send a close frame on all opened connections anyway.

@becvert
Copy link
Owner

becvert commented Jan 25, 2017

Hold on. I'm onto something. I'll update the branch in a few hours. wait for it!

@becvert
Copy link
Owner

becvert commented Jan 26, 2017

Please update the branch and have a look. Thanks

@bugnano
Copy link
Contributor Author

bugnano commented Jan 31, 2017

Ok, the latest update in the 1.4.0 branch seems to have fixed the crash. Thank you.

@becvert
Copy link
Owner

becvert commented Jan 31, 2017

Good. I'll release the branch.

@becvert becvert closed this as completed Feb 1, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants