The C based gRPC (C++, Python, Ruby, Objective-C, PHP, C#)
https://grpc.io/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.1 KiB
90 lines
3.1 KiB
/* |
|
* |
|
* Copyright 2016 gRPC authors. |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*/ |
|
|
|
#import "GRPCConnectivityMonitor.h" |
|
|
|
#include <netinet/in.h> |
|
|
|
NSString *kGRPCConnectivityNotification = @"kGRPCConnectivityNotification"; |
|
|
|
static SCNetworkReachabilityRef reachability; |
|
static GRPCConnectivityStatus currentStatus; |
|
|
|
// Aggregate information in flags into network status. |
|
GRPCConnectivityStatus CalculateConnectivityStatus(SCNetworkReachabilityFlags flags) { |
|
GRPCConnectivityStatus result = GRPCConnectivityUnknown; |
|
if (((flags & kSCNetworkReachabilityFlagsReachable) == 0) || |
|
((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0)) { |
|
return GRPCConnectivityNoNetwork; |
|
} |
|
result = GRPCConnectivityWiFi; |
|
#if TARGET_OS_IPHONE |
|
if (flags & kSCNetworkReachabilityFlagsIsWWAN) { |
|
return result = GRPCConnectivityCellular; |
|
} |
|
#endif |
|
return result; |
|
} |
|
|
|
static void ReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, |
|
void *info) { |
|
GRPCConnectivityStatus newStatus = CalculateConnectivityStatus(flags); |
|
|
|
if (newStatus != currentStatus) { |
|
[[NSNotificationCenter defaultCenter] postNotificationName:kGRPCConnectivityNotification |
|
object:nil]; |
|
currentStatus = newStatus; |
|
} |
|
} |
|
|
|
@implementation GRPCConnectivityMonitor |
|
|
|
+ (void)initialize { |
|
if (self == [GRPCConnectivityMonitor self]) { |
|
struct sockaddr_in addr = {0}; |
|
addr.sin_len = sizeof(addr); |
|
addr.sin_family = AF_INET; |
|
reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&addr); |
|
currentStatus = GRPCConnectivityUnknown; |
|
|
|
SCNetworkConnectionFlags flags; |
|
if (SCNetworkReachabilityGetFlags(reachability, &flags)) { |
|
currentStatus = CalculateConnectivityStatus(flags); |
|
} |
|
|
|
SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; |
|
if (!SCNetworkReachabilitySetCallback(reachability, ReachabilityCallback, &context) || |
|
!SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), |
|
kCFRunLoopCommonModes)) { |
|
NSLog(@"gRPC connectivity monitor fail to set"); |
|
} |
|
} |
|
} |
|
|
|
+ (void)registerObserver:(id)observer selector:(SEL)selector { |
|
[[NSNotificationCenter defaultCenter] addObserver:observer |
|
selector:selector |
|
name:kGRPCConnectivityNotification |
|
object:nil]; |
|
} |
|
|
|
+ (void)unregisterObserver:(id)observer { |
|
[[NSNotificationCenter defaultCenter] removeObserver:observer]; |
|
} |
|
|
|
@end
|
|
|