grpc-swift icon indicating copy to clipboard operation
grpc-swift copied to clipboard

Callback not getting called from ClientNetworkMonitor cellularDidChange method

Open tikekar opened this issue 6 years ago • 5 comments

New Issue Checklist

Issue Description

When I turn the airplane mode on and off from wifi, the cellularDidChange method of ClientNetworkMonitor class gets called. But the callback "self.callback(State..." doesn't get called. If I remove the if() statement surrounding it, it gets called.

// commenting the if statement works.
// if let newCellularName = newCellularName, self.cellularName != newCellularName {
        self.cellularName = newCellularName
        self.callback(State(lastChange: .cellularTechnology(technology: newCellularName ?? ""),
                            isReachable: self.isReachable ?? false))
      // }
Complete output when running grpc-swift, including the stack trace and command used
[INSERT OUTPUT HERE]

Environment

Key Value
OS Version x.x.x
Swift Version x.x.x
Xcode Version x.x.x
gRPC-Swift Version x.x.x
gRPC-Swift Version x.x.x
protoc Version x.x.x
protoc-gen-swift Version x.x.x
protoc-gen-swiftgrpc Version x.x.x

tikekar avatar Jul 25 '19 22:07 tikekar

Thanks for filing, @tikekar. What problems is this causing for your application? This API is supposed to be used for restarting a channel when we know it needs to be switched to another reachable connection. In this case, there are no reachable connections.

From what I've seen in past experimentation, disabling airplane mode will:

  • allow the connection to automatically resume if it hasn't timed out
  • receive data that was missed while airplane mode was enabled (if the connection hasn't timed out)
  • send a notification through this interface notifying you of a new connection

Are you not seeing this behavior?

rebello95 avatar Jul 27 '19 01:07 rebello95

My use case with ClientNetworkMonitor so far is -

  • Whenever reachability changes, I want to call the callback and notify user whether internet is available or not.

Not sure if I am missing here something but can you help answer following questions? Questions -

  • If there are no reachable connections, what happens to the channel then? when I put my phone on airplane mode, I was assuming that I should be able to call the self.callback.
  • I was little confused regarding when should the reachabilityDidChange get called and when should cellularDidChange get called? First I thought that reachabilityDidChange get triggered when I set the airplane mode. But instead it calls cellularDidChange for me.

Following is my code for ClientNetworkMonitor initialization:

self.clientNetworkMonitor = ClientNetworkMonitor(callback: { (state) in
      
            if state.isReachable {
                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNetworkStateChanged), object: NetworkState.connected)
            }
            else {
                NotificationCenter.default.post(name: NSNotification.Name(rawValue: kNetworkStateChanged), object: NetworkState.noInternet)
            }
        })

tikekar avatar Jul 28 '19 21:07 tikekar

If there are no reachable connections, what happens to the channel then? when I put my phone on airplane mode, I was assuming that I should be able to call the self.callback.

I just ran a test locally, and on my device I'm seeing the following output when starting the app and toggling airplane mode on/off:

// Launch with cellular + wifi enabled
Changed: cellularTechnology(technology: "CTRadioAccessTechnologyLTE"), isReachable: true
// Turn on airplane mode
Changed: reachability(isReachable: false), isReachable: false
Changed: reachability(isReachable: false), isReachable: false
Changed: cellularTechnology(technology: "CTRadioAccessTechnologyLTE"), isReachable: false
// Turn off airplane mode
Changed: cellularTechnology(technology: "CTRadioAccessTechnologyLTE"), isReachable: false
Changed: reachability(isReachable: true), isReachable: true
Changed: reachability(isReachable: true), isReachable: true
Changed: reachability(isReachable: true), isReachable: true

Based on this, it seems like you should be getting notified when airplane mode turns on and off - is that not the case?

I was little confused regarding when should the reachabilityDidChange get called and when should cellularDidChange get called? First I thought that reachabilityDidChange get triggered when I set the airplane mode. But instead it calls cellularDidChange for me.

Looks like we end up calling both here (guessing because the OS starts preferring WiFi over cellular when airplane mode turns on):

// Launch with only cellular enabled
Changed: cellularTechnology(technology: "CTRadioAccessTechnologyLTE"), isReachable: true
// Enable airplane mode
Changed: cellularToWifi, isReachable: false
Changed: reachability(isReachable: false), isReachable: false
// Disable airplane mode
Changed: reachability(isReachable: true), isReachable: true

rebello95 avatar Aug 10 '19 15:08 rebello95

Yes for me somehow when I change the airplane mode ON, it calls cellularDidChange only. Anyway currently our grpc connections work only on our company's wifi as we are still working on it and not released it yet. Thus I am still working on its full testing. But one question - Does the isReachable flag only tied to internet connection (network) availability? Or the isReachable can be false when the connect stream drops or channel drops for any other reason?

tikekar avatar Aug 12 '19 19:08 tikekar

Does the isReachable flag only tied to internet connection (network) availability? Or the isReachable can be false when the connect stream drops or channel drops for any other reason?

This only applies to network reachability. If the channel drops for another reason, the channel should shut down / time out.

rebello95 avatar Aug 16 '19 20:08 rebello95