davidstump / SwiftPhoenixClient

Connect your Phoenix and iOS applications through WebSockets!
MIT License
506 stars 146 forks source link

Problems with connections closing and not re-establishing #214

Open JetForMe opened 2 years ago

JetForMe commented 2 years ago

What is the default expected behavior in the presence of severe network errors? We're seeing a general behavior of SwiftPhoenixClient disconnecting and not re-connecting.

Interestingly, we see two separate behaviors. Our app connects to the same ws URL with two different Sockets, and then a single channel is created for each Socket, each with a different topic (one for "auction", one for "chat").

To reproduce the behavior, I ran the code on my iPhone and set the Network Link Conditioner to "Very Bad Network." But note that our users (and even some of our devs) are reporting apparent disconnects too frequently in the field.

I see a lot of heartbeat timeouts on the auction channel, but never on the chat channel. Eventually I’ll see timeouts on the transport, and then things just close:

transport, heartbeat timeout. Attempting to re-establish connection
transport, close

What can we do here to try to keep re-establishing the connection? Does adding an error or close callback give me a good place to re-connect?

dsrees commented 2 years ago

The reconnection logic Should Just Work™️ but there may be some edge cases. When setting Network Link Conditioner to "Very Bad Network", are you able to reproduce the issue? Are you using Starscream or URLSessionWebSocketTask?

Also, I would recommend only using a single Socket connection and then opening multiple channels through that socket.

JetForMe commented 2 years ago

Yes, it sometimes reproduces with Very Bad Network. I'm using URLSessionWebSocketTask (rather, I’m NOT using Starscream, so I assume it's using URLSessionWebSocketTask).

Also, I would recommend only using a single Socket connection and then opening multiple channels through that socket.

Interesting, our back-end guys recommended separate sockets.

dsrees commented 2 years ago

The client (which is a port of how the phoenix.js client was designed) is built to multiplex over a single socket connection. All that a channel is, is filtering topics to different callbacks. As long as your sockets are both pointing to the same URL and using the same credentials then you should use a single socket.

If you logged messages on each socket, i bet you'll see the same messages on each for both channels, unless your backend team is for some reason filtering messages to each socket based on open channels.

That said, I'm not 100% sure why one channel disconnects and the other does not, but I would recommend you try using a single socket and seeing if the issue persists

JetForMe commented 2 years ago

A little more investigation: It seems that generally, channels do reconnect. Socket disconnects are a little less reliable, although not 100% so. It would be nice if there was more logging of re-connection-in-the-face-of-errors attempts.