grpc-swift: Stream stops receiving messages after changing connection from Wifi to Cellular

Question Checklist

Question Subject

How to restart a stream after changing connection from Wifi to Cellular?

Question Description

I use SwiftGRPC in iOS app and I have the client like:

service UpdateService {
    rpc GetUpdates (UpdatesConnection) returns (stream Update);
}

I subscribe on connectivity state of channel:

updateClient.channel.subscribe { connectivityState in
...
}

Then I make request to create stream from server:

let call = try updateClient.getUpdates(UpdatesConnection()) { result in
	switch result.statusCode {
		…
	} 
}

When I change iPhone connection from Wifi to Cellular, the stream stops receiving messages from server but the connectivityState (subscription to connectivity state) and result.statusCode keeping silent. After few minutes connectivityState gets .idle and result.statusCode gets . unavailable. When result.statusCode gets . unavailable I trying to call let call = try updateClient.getUpdates(UpdatesConnection()) again, but stream doesn’t receive messages anyway. So I’ve added subscription on iOS network state (Reachability) and I destroy the updateClient and recreate it when connection get changed from WIfi to Cellular. Only after destroying and recreating the updateClient the stream works properly - it receive messages. Am I doing right? Maybe my way is wrong and there is another way to restart stream after changing connection?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 2
  • Comments: 19 (3 by maintainers)

Commits related to this issue

Most upvoted comments

Took a long ride this morning going around San Francisco evaluating how well iOS is able to maintain a gRPC connection. Things I noticed (pretty much confirming my comments above):

  • Switching between wifi <> cellular causes connections to silently disconnect
  • Switching between 3G <> LTE causes connections to silently disconnect
  • gRPC does time out and shut down channels as expected in cases of poor connectivity
  • Backgrounding the app and foregrounding it again a few seconds later doesn’t kill the connection - previously streamed responses come in upon foregrounding
  • Switching between cell towers seems to work fine and not cause a disconnection

The changes that cause silent disconnects were caught by the observer I added in https://github.com/grpc/grpc-swift/pull/387, so consumers should be able to resolve these issues by utilizing that.

I also just issued a 0.8.0 release which includes these changes.

Sounds good. I’ll go ahead and do the following:

  • Add functionality for shutting down channels (in PR: https://github.com/grpc/grpc-swift/pull/384)
  • Implement a system that observes these types of changes on the mobile client and notifies a callback as necessary
  • Write up known issues and guidance for how to avoid these on the client