|
|
|
@ -15,8 +15,10 @@ The expected gRPC iOS channel and network transition behaviors are: |
|
|
|
|
happens when |
|
|
|
|
* The network interface is no longer available, e.g. WiFi or cellular |
|
|
|
|
interface is turned off or goes offline, airplane mode turned on, etc; |
|
|
|
|
* The underlying TCP connection is no longer valid, e.g. WiFi connects to another hotspot, cellular data switched from LTE to 4G, etc; |
|
|
|
|
* A network interface more preferable by the OS is valid, e.g. WiFi gets connected when the channel connects via cellular. |
|
|
|
|
* The underlying TCP connection is no longer valid, e.g. WiFi connects to |
|
|
|
|
another hotspot, cellular data switched from LTE to 4G, etc; |
|
|
|
|
* A network interface more preferable by the OS is valid, e.g. WiFi gets |
|
|
|
|
connected when the channel is already connected via cellular. |
|
|
|
|
* A channel in TRANSIENT\_FAILURE state attempts reconnection on start of the |
|
|
|
|
next call to the same host, but only after a certain backoff period (see |
|
|
|
|
corresponding |
|
|
|
@ -27,34 +29,38 @@ The expected gRPC iOS channel and network transition behaviors are: |
|
|
|
|
* Conncetion failed; calls will be failed and return UNAVAILABLE status code; |
|
|
|
|
* The call's deadline is reached; the call will fail and return |
|
|
|
|
DEADLINE\_EXCEEDED status code. |
|
|
|
|
The length of backoff period of a channel is reset whenever a connection |
|
|
|
|
attempt is successful. |
|
|
|
|
|
|
|
|
|
## Implementations |
|
|
|
|
### gRPC iOS with TCP Sockets |
|
|
|
|
gRPC's default implementation is to use TCP sockets for networking. It turns |
|
|
|
|
out that although Apple supports this type of usage, it is [not recommended by |
|
|
|
|
Apple](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html) |
|
|
|
|
and is also flawed. |
|
|
|
|
and has some issues described below. |
|
|
|
|
|
|
|
|
|
#### TCP Sockets Issues |
|
|
|
|
#### Issues with TCP Sockets |
|
|
|
|
The TCP sockets on iOS is flawed in that it does not reflect the viability of |
|
|
|
|
the channel connection. Particularly, we found the following issues related to |
|
|
|
|
TCP sockets: |
|
|
|
|
* When a TCP sockets connection is established on cellular data and WiFi |
|
|
|
|
the channel connection. Particularly, we observed the following issues when |
|
|
|
|
using TCP sockets: |
|
|
|
|
* When a TCP socket connection is established on cellular data and WiFi |
|
|
|
|
becomes available, the TCP socket neither return an error event nor continue |
|
|
|
|
sending/receiving data on it, but still accepts write on it. |
|
|
|
|
* The TCP sockets does not report certain events that happens in the |
|
|
|
|
* A TCP sockets does not report certain events that happen in the |
|
|
|
|
background. When a TCP connection breaks in the background for the reason |
|
|
|
|
like WiFi connects to another hotspot, the socket neither return an error nor |
|
|
|
|
continue sending/receiving data on it, but still accepts write on it. |
|
|
|
|
In both situations, the user will see the call hangs for an extended period of |
|
|
|
|
time before the TCP socket times out. |
|
|
|
|
|
|
|
|
|
#### gRPC iOS resolutions |
|
|
|
|
#### gRPC iOS library's resolution to TCP socket issues |
|
|
|
|
We introduced |
|
|
|
|
[`ConnectivityMonitor`](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/SocketsAndStreams/SocketsAndStreams.html) |
|
|
|
|
in gRPC iOS library to alleviate these issues in TCP sockets, which changes the |
|
|
|
|
network transition behaviors a bit. |
|
|
|
|
in gRPC iOS library v0.14.0 to alleviate these issues in TCP sockets, |
|
|
|
|
which changes the network transition behaviors a bit. |
|
|
|
|
|
|
|
|
|
We classfy network connectivity state of the device into three categories based |
|
|
|
|
on flags obtained from `SCNetworkReachability` API: |
|
|
|
|
We classify network connectivity state of the device into three categories |
|
|
|
|
based on flags obtained from `SCNetworkReachability` API: |
|
|
|
|
|
|
|
|
|
| Reachable | ConnectionRequired | IsWWAN | **Category** | |
|
|
|
|
|:---------:|:------------------:|:------:|:------------:| |
|
|
|
@ -74,13 +80,13 @@ To solve that issue the best solution is to switch to CFStream implementation |
|
|
|
|
which eliminates all of them. |
|
|
|
|
|
|
|
|
|
### gRPC iOS with CFStream |
|
|
|
|
gRPC iOS with CFStream implementation uses Apple's networking API to make |
|
|
|
|
connections. It resolves the issues above that is known to TCP sockets on iOS. |
|
|
|
|
Users are recommended to use this implementation rather than TCP socket |
|
|
|
|
implementation. The detailed behavior of streams in CFStream is not documented |
|
|
|
|
by Apple, but our experiments show that it accords to the expected behaviors. |
|
|
|
|
With CFStream implementation, an event is always received when the underlying |
|
|
|
|
connection is no longer viable. For more detailed information and usages of |
|
|
|
|
CFStream implementation, refer to the |
|
|
|
|
gRPC iOS with CFStream implementation (introduced in v1.13.0) uses Apple's |
|
|
|
|
networking API to make connections. It resolves the issues with TCP sockets |
|
|
|
|
mentioned above. Users are recommended to use this implementation rather than |
|
|
|
|
TCP socket implementation. The detailed behavior of streams in CFStream is not |
|
|
|
|
documented by Apple, but our experiments show that it accords to the expected |
|
|
|
|
behaviors. With CFStream implementation, an event is always received when the |
|
|
|
|
underlying connection is no longer viable. For more detailed information and |
|
|
|
|
usages of CFStream implementation, refer to the |
|
|
|
|
[user guide](https://github.com/grpc/grpc/blob/master/src/objective-c/README-CFSTREAM.md). |
|
|
|
|
|
|
|
|
|