@onekeyfe/react-native-jpush 0.0.0-stage → 6.7.0-23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +56 -2
- package/ReactNativeJpush.podspec +66 -0
- package/android/CMakeLists.txt +24 -0
- package/android/build.gradle +144 -0
- package/android/fcm/build.gradle +36 -0
- package/android/fcm/consumer-rules.pro +2 -0
- package/android/fcm/src/main/AndroidManifest.xml +25 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmInitProvider.java +25 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmMessagingService.java +84 -0
- package/android/fcm/src/main/java/com/onekey/jpush/fcm/FcmPushManager.java +69 -0
- package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmAdapterTest.java +684 -0
- package/android/fcm/src/test/java/com/onekey/jpush/fcm/FcmManifestTest.java +54 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +143 -0
- package/android/src/main/cpp/cpp-adapter.cpp +6 -0
- package/android/src/main/java/cn/android/service/JTransitActivity.java +19 -0
- package/android/src/main/java/cn/jiguang/android/BuildConfig.java +10 -0
- package/android/src/main/java/cn/jiguang/android/IDataShare.java +190 -0
- package/android/src/main/java/cn/jiguang/api/BaseLogger.java +82 -0
- package/android/src/main/java/cn/jiguang/api/JAction.java +22 -0
- package/android/src/main/java/cn/jiguang/api/JActionExtra.java +21 -0
- package/android/src/main/java/cn/jiguang/api/JAnalyticsAction.java +11 -0
- package/android/src/main/java/cn/jiguang/api/JCoreInterface.java +228 -0
- package/android/src/main/java/cn/jiguang/api/JCoreManager.java +156 -0
- package/android/src/main/java/cn/jiguang/api/JDispatchAction.java +66 -0
- package/android/src/main/java/cn/jiguang/api/MultiSpHelper.java +114 -0
- package/android/src/main/java/cn/jiguang/api/ReportCallBack.java +9 -0
- package/android/src/main/java/cn/jiguang/api/SdkType.java +13 -0
- package/android/src/main/java/cn/jiguang/api/utils/JCollectionAuth.java +28 -0
- package/android/src/main/java/cn/jiguang/core/JCoreCrypto.java +545 -0
- package/android/src/main/java/cn/jiguang/core/JCoreStorage.java +737 -0
- package/android/src/main/java/cn/jiguang/core/JCoreTcpEngine.java +1395 -0
- package/android/src/main/java/cn/jiguang/core/JCoreWireCodec.java +1716 -0
- package/android/src/main/java/cn/jiguang/internal/ActionManager.java +63 -0
- package/android/src/main/java/cn/jiguang/internal/JConstants.java +61 -0
- package/android/src/main/java/cn/jiguang/internal/JCoreHelperAction.java +12 -0
- package/android/src/main/java/cn/jiguang/internal/JCoreInternalHelper.java +102 -0
- package/android/src/main/java/cn/jiguang/net/DefaultHostVerifier.java +40 -0
- package/android/src/main/java/cn/jiguang/net/HttpRequest.java +78 -0
- package/android/src/main/java/cn/jiguang/net/HttpResponse.java +48 -0
- package/android/src/main/java/cn/jiguang/net/HttpUtils.java +106 -0
- package/android/src/main/java/cn/jiguang/plugins/core/JCoreModule.java +91 -0
- package/android/src/main/java/cn/jiguang/plugins/core/JCorePackage.java +27 -0
- package/android/src/main/java/cn/jiguang/plugins/push/JPushModule.java +773 -0
- package/android/src/main/java/cn/jiguang/plugins/push/JPushPackage.java +25 -0
- package/android/src/main/java/cn/jiguang/plugins/push/common/JConstants.java +88 -0
- package/android/src/main/java/cn/jiguang/plugins/push/common/JLogger.java +122 -0
- package/android/src/main/java/cn/jiguang/plugins/push/helper/JPushHelper.java +710 -0
- package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushBroadcastReceiver.java +37 -0
- package/android/src/main/java/cn/jiguang/plugins/push/receiver/JPushModuleReceiver.java +264 -0
- package/android/src/main/java/cn/jiguang/plugins/service/JCoreModuleService.java +7 -0
- package/android/src/main/java/cn/jpush/android/api/BasicPushNotificationBuilder.java +83 -0
- package/android/src/main/java/cn/jpush/android/api/CallBackParams.java +50 -0
- package/android/src/main/java/cn/jpush/android/api/CmdMessage.java +33 -0
- package/android/src/main/java/cn/jpush/android/api/CustomMessage.java +28 -0
- package/android/src/main/java/cn/jpush/android/api/CustomPushNotificationBuilder.java +81 -0
- package/android/src/main/java/cn/jpush/android/api/DefaultPushNotificationBuilder.java +90 -0
- package/android/src/main/java/cn/jpush/android/api/InAppSlotParams.java +65 -0
- package/android/src/main/java/cn/jpush/android/api/InstrumentedActivity.java +17 -0
- package/android/src/main/java/cn/jpush/android/api/InstrumentedListActivity.java +17 -0
- package/android/src/main/java/cn/jpush/android/api/JPushInterface.java +490 -0
- package/android/src/main/java/cn/jpush/android/api/JPushMessage.java +121 -0
- package/android/src/main/java/cn/jpush/android/api/JThirdPlatFormInterface.java +247 -0
- package/android/src/main/java/cn/jpush/android/api/MultiActionsNotificationBuilder.java +72 -0
- package/android/src/main/java/cn/jpush/android/api/NotificationCustomButton.java +50 -0
- package/android/src/main/java/cn/jpush/android/api/NotificationMessage.java +67 -0
- package/android/src/main/java/cn/jpush/android/api/PushNotificationBuilder.java +13 -0
- package/android/src/main/java/cn/jpush/android/api/TagAliasCallback.java +8 -0
- package/android/src/main/java/cn/jpush/android/data/JPushCollectControl.java +96 -0
- package/android/src/main/java/cn/jpush/android/data/JPushConfig.java +79 -0
- package/android/src/main/java/cn/jpush/android/data/JPushConfigEx.java +41 -0
- package/android/src/main/java/cn/jpush/android/data/JPushLocalNotification.java +155 -0
- package/android/src/main/java/cn/jpush/android/helper/JCoreHelper.java +70 -0
- package/android/src/main/java/cn/jpush/android/helper/Logger.java +82 -0
- package/android/src/main/java/cn/jpush/android/local/ActionHelper.java +1293 -0
- package/android/src/main/java/cn/jpush/android/local/ActivityLifeCallBack.java +47 -0
- package/android/src/main/java/cn/jpush/android/local/JPushAction.java +67 -0
- package/android/src/main/java/cn/jpush/android/local/JPushConstants.java +34 -0
- package/android/src/main/java/cn/jpush/android/local/JPushResponse.java +26 -0
- package/android/src/main/java/cn/jpush/android/local/ProxyActivityAction.java +34 -0
- package/android/src/main/java/cn/jpush/android/service/AlarmReceiver.java +15 -0
- package/android/src/main/java/cn/jpush/android/service/BActivity.java +19 -0
- package/android/src/main/java/cn/jpush/android/service/DActivity.java +19 -0
- package/android/src/main/java/cn/jpush/android/service/DaemonService.java +17 -0
- package/android/src/main/java/cn/jpush/android/service/DataProvider.java +136 -0
- package/android/src/main/java/cn/jpush/android/service/DataShare.java +129 -0
- package/android/src/main/java/cn/jpush/android/service/DownloadProvider.java +139 -0
- package/android/src/main/java/cn/jpush/android/service/InitProvider.java +48 -0
- package/android/src/main/java/cn/jpush/android/service/JCommonService.java +79 -0
- package/android/src/main/java/cn/jpush/android/service/JNotifyActivity.java +28 -0
- package/android/src/main/java/cn/jpush/android/service/JPushMessageReceiver.java +94 -0
- package/android/src/main/java/cn/jpush/android/service/PushReceiver.java +26 -0
- package/android/src/main/java/cn/jpush/android/service/PushService.java +28 -0
- package/android/src/main/java/cn/jpush/android/service/SchedulerReceiver.java +17 -0
- package/android/src/main/java/cn/jpush/android/service/TagAliasReceiver.java +11 -0
- package/android/src/main/java/cn/jpush/android/service/WakedResultReceiver.java +24 -0
- package/android/src/main/java/cn/jpush/android/ui/FullScreenView.java +11 -0
- package/android/src/main/java/cn/jpush/android/ui/PopWinActivity.java +16 -0
- package/android/src/main/java/cn/jpush/android/ui/PushActivity.java +27 -0
- package/android/src/main/java/cn/jpush/android/ui/RoundedImageView.java +63 -0
- package/android/src/main/java/cn/jpush/android/ui/ShadowViewCard.java +56 -0
- package/android/src/main/java/cn/jpush/android/ups/ICallbackResult.java +5 -0
- package/android/src/main/java/cn/jpush/android/ups/JPushUPSManager.java +37 -0
- package/android/src/main/java/cn/jpush/android/ups/TokenResult.java +47 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSRegisterCallBack.java +4 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSTurnCallBack.java +4 -0
- package/android/src/main/java/cn/jpush/android/ups/UPSUnRegisterCallBack.java +4 -0
- package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpush.kt +455 -0
- package/android/src/main/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushPackage.kt +50 -0
- package/android/src/main/res/values/jpush_string.xml +7 -0
- package/android/src/main/res/values/jpush_style.xml +22 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushCloudHandshakeTest.java +110 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/JPushHandshakeFailureTest.java +73 -0
- package/android/src/test/java/com/margelo/nitro/reactnativejpush/ReactNativeJpushProtocolTest.java +908 -0
- package/ios/ReactNativeJpush.swift +522 -0
- package/ios/bridge/RCTJCoreModule.h +5 -0
- package/ios/bridge/RCTJCoreModule.m +31 -0
- package/ios/bridge/RCTJPushEventQueue.h +14 -0
- package/ios/bridge/RCTJPushEventQueue.m +23 -0
- package/ios/bridge/RCTJPushModule.h +37 -0
- package/ios/bridge/RCTJPushModule.m +1165 -0
- package/ios/include/JCOREService.h +3 -0
- package/ios/include/JGCOREAPI.h +14 -0
- package/ios/include/JGInforCollectionAuth.h +17 -0
- package/ios/include/JGInforCollectionAuthItems.h +2 -0
- package/ios/include/JGPushNotificationTrigger.h +2 -0
- package/ios/include/JPUSHService.h +359 -0
- package/ios/jcore/JCOREConfiguration.h +141 -0
- package/ios/jcore/JCOREConfiguration.m +703 -0
- package/ios/jcore/JCORECrypto.h +73 -0
- package/ios/jcore/JCORECrypto.m +649 -0
- package/ios/jcore/JCORESisResolver.h +56 -0
- package/ios/jcore/JCORESisResolver.m +525 -0
- package/ios/jcore/JCORETcpSession.h +42 -0
- package/ios/jcore/JCORETcpSession.m +956 -0
- package/ios/jcore/JCOREWireProtocol.h +274 -0
- package/ios/jcore/JCOREWireProtocol.m +1453 -0
- package/ios/jpush/JPUSHModels.m +214 -0
- package/ios/jpush/JPUSHNotificationManager.h +34 -0
- package/ios/jpush/JPUSHNotificationManager.m +360 -0
- package/ios/jpush/JPUSHService.m +794 -0
- package/ios/tests/ReactNativeJpushTests.m +148 -0
- package/lib/module/ReactNativeJpush.nitro.js +4 -0
- package/lib/module/ReactNativeJpush.nitro.js.map +1 -0
- package/lib/module/index.js +801 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/ReactNativeJpush.nitro.d.ts +60 -0
- package/lib/typescript/src/ReactNativeJpush.nitro.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +235 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/nitro.json +23 -0
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +75 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.cpp +310 -0
- package/nitrogen/generated/android/c++/JHybridReactNativeJpushSpec.hpp +115 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_bool.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/Func_void_std__string_std__string.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/HybridReactNativeJpushSpec.kt +274 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/reactnativejpush/reactnativejpushOnLoad.kt +35 -0
- package/nitrogen/generated/android/reactnativejpush+autolinking.cmake +81 -0
- package/nitrogen/generated/android/reactnativejpush+autolinking.gradle +27 -0
- package/nitrogen/generated/android/reactnativejpushOnLoad.cpp +58 -0
- package/nitrogen/generated/android/reactnativejpushOnLoad.hpp +34 -0
- package/nitrogen/generated/ios/ReactNativeJpush+autolinking.rb +62 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.cpp +49 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Bridge.hpp +147 -0
- package/nitrogen/generated/ios/ReactNativeJpush-Swift-Cxx-Umbrella.hpp +46 -0
- package/nitrogen/generated/ios/ReactNativeJpushAutolinking.mm +33 -0
- package/nitrogen/generated/ios/ReactNativeJpushAutolinking.swift +26 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridReactNativeJpushSpecSwift.hpp +402 -0
- package/nitrogen/generated/ios/swift/Func_void_bool.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec.swift +107 -0
- package/nitrogen/generated/ios/swift/HybridReactNativeJpushSpec_cxx.swift +723 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.cpp +73 -0
- package/nitrogen/generated/shared/c++/HybridReactNativeJpushSpec.hpp +116 -0
- package/package.json +174 -4
- package/src/ReactNativeJpush.nitro.ts +93 -0
- package/src/index.tsx +1090 -0
|
@@ -0,0 +1,956 @@
|
|
|
1
|
+
#import "JCORETcpSession.h"
|
|
2
|
+
#import "JCOREConfiguration.h"
|
|
3
|
+
#import "JCORESisResolver.h"
|
|
4
|
+
#if __has_include("JPUSHService.h")
|
|
5
|
+
#import "JPUSHService.h"
|
|
6
|
+
#else
|
|
7
|
+
#import "../include/JPUSHService.h"
|
|
8
|
+
#endif
|
|
9
|
+
#import <Network/Network.h>
|
|
10
|
+
#if __has_include(<UIKit/UIKit.h>)
|
|
11
|
+
#import <UIKit/UIKit.h>
|
|
12
|
+
#endif
|
|
13
|
+
|
|
14
|
+
NSString *const kJPFNetworkIsConnectingNotification = @"kJPFNetworkIsConnectingNotification";
|
|
15
|
+
NSString *const kJPFNetworkDidSetupNotification = @"kJPFNetworkDidSetupNotification";
|
|
16
|
+
NSString *const kJPFNetworkDidCloseNotification = @"kJPFNetworkDidCloseNotification";
|
|
17
|
+
NSString *const kJPFNetworkDidRegisterNotification = @"kJPFNetworkDidRegisterNotification";
|
|
18
|
+
NSString *const kJPFNetworkFailedRegisterNotification = @"kJPFNetworkFailedRegisterNotification";
|
|
19
|
+
NSString *const kJPFNetworkDidLoginNotification = @"kJPFNetworkDidLoginNotification";
|
|
20
|
+
NSString *const kJPFNetworkDidReceiveMessageNotification = @"kJPFNetworkDidReceiveMessageNotification";
|
|
21
|
+
NSString *const kJPFServiceErrorNotification = @"kJPFServiceErrorNotification";
|
|
22
|
+
|
|
23
|
+
@interface JCOREQueuedWireRequest : NSObject
|
|
24
|
+
@property (nonatomic, assign) uint8_t command;
|
|
25
|
+
@property (nonatomic, assign) uint8_t version;
|
|
26
|
+
@property (nonatomic, strong) NSData *bodyData;
|
|
27
|
+
@property (nonatomic, copy, nullable) JCORETcpResponseHandler completion;
|
|
28
|
+
@end
|
|
29
|
+
|
|
30
|
+
@implementation JCOREQueuedWireRequest
|
|
31
|
+
@end
|
|
32
|
+
|
|
33
|
+
@interface JCOREInFlightRequest : NSObject
|
|
34
|
+
@property (nonatomic, assign) uint16_t requestId;
|
|
35
|
+
@property (nonatomic, assign) uint8_t command;
|
|
36
|
+
@property (nonatomic, assign) uint8_t version;
|
|
37
|
+
@property (nonatomic, strong) NSData *packetData;
|
|
38
|
+
@property (nonatomic, copy, nullable) JCORETcpResponseHandler completion;
|
|
39
|
+
@property (nonatomic, strong, nullable) dispatch_source_t resendTimer;
|
|
40
|
+
@property (nonatomic, strong, nullable) dispatch_source_t timeoutTimer;
|
|
41
|
+
- (void)cancelTimers;
|
|
42
|
+
@end
|
|
43
|
+
|
|
44
|
+
@implementation JCOREInFlightRequest
|
|
45
|
+
- (void)cancelTimers {
|
|
46
|
+
if (_resendTimer != nil) {
|
|
47
|
+
dispatch_source_cancel(_resendTimer);
|
|
48
|
+
_resendTimer = nil;
|
|
49
|
+
}
|
|
50
|
+
if (_timeoutTimer != nil) {
|
|
51
|
+
dispatch_source_cancel(_timeoutTimer);
|
|
52
|
+
_timeoutTimer = nil;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
@end
|
|
56
|
+
|
|
57
|
+
@interface JCORETcpSession () {
|
|
58
|
+
dispatch_queue_t _sessionQueue;
|
|
59
|
+
nw_connection_t _connection;
|
|
60
|
+
nw_path_monitor_t _pathMonitor;
|
|
61
|
+
dispatch_source_t _heartbeatTimer;
|
|
62
|
+
dispatch_source_t _connectTimeoutTimer;
|
|
63
|
+
dispatch_source_t _reconnectTimer;
|
|
64
|
+
NSMutableData *_receiveBuffer;
|
|
65
|
+
NSMutableDictionary<NSNumber *, JCOREInFlightRequest *> *_inFlightRequests;
|
|
66
|
+
NSMutableArray<JCOREQueuedWireRequest *> *_queuedRequests;
|
|
67
|
+
NSArray<JCORESisEndpoint *> *_candidateEndpoints;
|
|
68
|
+
NSUInteger _currentEndpointIndex;
|
|
69
|
+
NSUInteger _reconnectAttempt;
|
|
70
|
+
uint32_t _sessionId;
|
|
71
|
+
uint16_t _serverVersion;
|
|
72
|
+
uint32_t _serverTimestamp;
|
|
73
|
+
BOOL _connecting;
|
|
74
|
+
BOOL _connected;
|
|
75
|
+
BOOL _loggedIn;
|
|
76
|
+
BOOL _userDisconnected;
|
|
77
|
+
NSString *_lastReportedDeviceTokenHex;
|
|
78
|
+
NSString *_lastReportedVoipTokenHex;
|
|
79
|
+
}
|
|
80
|
+
@end
|
|
81
|
+
|
|
82
|
+
@implementation JCORETcpSession
|
|
83
|
+
|
|
84
|
+
+ (instancetype)shared {
|
|
85
|
+
static JCORETcpSession *instance = nil;
|
|
86
|
+
static dispatch_once_t onceToken;
|
|
87
|
+
dispatch_once(&onceToken, ^{
|
|
88
|
+
instance = [[JCORETcpSession alloc] init];
|
|
89
|
+
});
|
|
90
|
+
return instance;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
- (instancetype)init {
|
|
94
|
+
self = [super init];
|
|
95
|
+
if (self) {
|
|
96
|
+
_sessionQueue = dispatch_queue_create("cn.jiguang.jcore.tcp.session", DISPATCH_QUEUE_SERIAL);
|
|
97
|
+
_receiveBuffer = [NSMutableData data];
|
|
98
|
+
_inFlightRequests = [NSMutableDictionary dictionary];
|
|
99
|
+
_queuedRequests = [NSMutableArray array];
|
|
100
|
+
[self setupNetworkAndLifecycleMonitors];
|
|
101
|
+
}
|
|
102
|
+
return self;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
- (void)setupNetworkAndLifecycleMonitors {
|
|
106
|
+
nw_path_monitor_t monitor = nw_path_monitor_create();
|
|
107
|
+
if (monitor != nil) {
|
|
108
|
+
_pathMonitor = monitor;
|
|
109
|
+
nw_path_monitor_set_queue(monitor, _sessionQueue);
|
|
110
|
+
__weak typeof(self) weakSelf = self;
|
|
111
|
+
nw_path_monitor_set_update_handler(monitor, ^(nw_path_t path) {
|
|
112
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
113
|
+
if (!strongSelf) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (nw_path_get_status(path) == nw_path_status_satisfied) {
|
|
117
|
+
if (!strongSelf->_userDisconnected &&
|
|
118
|
+
!strongSelf->_connected &&
|
|
119
|
+
!strongSelf->_connecting &&
|
|
120
|
+
[JCOREConfiguration shared].appKey.length > 0 &&
|
|
121
|
+
![JCOREConfiguration shared].pushStopped) {
|
|
122
|
+
strongSelf->_reconnectAttempt = 0;
|
|
123
|
+
[strongSelf startLockedForceReconnect:NO];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
nw_path_monitor_start(monitor);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#if __has_include(<UIKit/UIKit.h>)
|
|
131
|
+
[[NSNotificationCenter defaultCenter] addObserver:self
|
|
132
|
+
selector:@selector(handleAppWillEnterForeground:)
|
|
133
|
+
name:UIApplicationWillEnterForegroundNotification
|
|
134
|
+
object:nil];
|
|
135
|
+
#endif
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
- (void)handleAppWillEnterForeground:(NSNotification *)note {
|
|
139
|
+
(void)note;
|
|
140
|
+
dispatch_async(_sessionQueue, ^{
|
|
141
|
+
if (self->_userDisconnected || [JCOREConfiguration shared].pushStopped) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (!self->_connected && !self->_connecting) {
|
|
145
|
+
self->_reconnectAttempt = 0;
|
|
146
|
+
[self startLockedForceReconnect:NO];
|
|
147
|
+
} else if (self->_connected && self->_loggedIn) {
|
|
148
|
+
NSData *hb = [JCOREWireProtocol buildHeartbeatPayloadWithPushStopped:[JCOREConfiguration shared].pushStopped];
|
|
149
|
+
[self sendRawCommandLocked:JCOREWireCommandHeartbeat version:8 bodyData:hb completion:nil];
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
- (BOOL)isConnected {
|
|
155
|
+
return _connected;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
- (BOOL)isLoggedIn {
|
|
159
|
+
return _loggedIn;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
- (uint32_t)sessionId {
|
|
163
|
+
return _sessionId;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
- (uint16_t)serverVersion {
|
|
167
|
+
return _serverVersion;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
- (uint32_t)serverTimestamp {
|
|
171
|
+
return _serverTimestamp;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
- (NSUInteger)reconnectAttemptCount {
|
|
175
|
+
return _reconnectAttempt;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
- (void)setCustomConnectHost:(NSString *)host
|
|
179
|
+
port:(uint16_t)port
|
|
180
|
+
useSSL:(BOOL)useSSL {
|
|
181
|
+
[[JCOREConfiguration shared] setCustomConnectHost:host port:port useSSL:useSSL];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
- (void)postNotificationOnMain:(NSString *)name userInfo:(nullable NSDictionary *)userInfo {
|
|
185
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
186
|
+
[[NSNotificationCenter defaultCenter] postNotificationName:name object:userInfo userInfo:userInfo];
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
- (void)startIfNeeded {
|
|
191
|
+
dispatch_async(_sessionQueue, ^{
|
|
192
|
+
self->_userDisconnected = NO;
|
|
193
|
+
[self startLockedForceReconnect:NO];
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
- (void)reconnect {
|
|
198
|
+
dispatch_async(_sessionQueue, ^{
|
|
199
|
+
self->_userDisconnected = NO;
|
|
200
|
+
self->_reconnectAttempt = 0;
|
|
201
|
+
[self startLockedForceReconnect:YES];
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
- (void)startLockedForceReconnect:(BOOL)forceReconnect {
|
|
206
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
207
|
+
if (config.appKey.length == 0 || config.pushStopped) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
[self cancelReconnectTimerLocked];
|
|
211
|
+
if (forceReconnect) {
|
|
212
|
+
[self tearDownConnectionLocked];
|
|
213
|
+
_connecting = NO;
|
|
214
|
+
}
|
|
215
|
+
if (_connected || _connecting) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
_connecting = YES;
|
|
219
|
+
_lastReportedDeviceTokenHex = nil;
|
|
220
|
+
_lastReportedVoipTokenHex = nil;
|
|
221
|
+
[self postNotificationOnMain:kJPFNetworkIsConnectingNotification userInfo:nil];
|
|
222
|
+
|
|
223
|
+
[[JCORESisResolver shared] resolveEndpointsWithCompletion:^(NSArray<JCORESisEndpoint *> *endpoints) {
|
|
224
|
+
dispatch_async(self->_sessionQueue, ^{
|
|
225
|
+
if (self->_userDisconnected || [JCOREConfiguration shared].pushStopped) {
|
|
226
|
+
self->_connecting = NO;
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (endpoints.count == 0) {
|
|
230
|
+
self->_connecting = NO;
|
|
231
|
+
[self scheduleReconnectLocked];
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
self->_candidateEndpoints = [endpoints copy];
|
|
235
|
+
self->_currentEndpointIndex = 0;
|
|
236
|
+
[self connectToCurrentCandidateLocked];
|
|
237
|
+
});
|
|
238
|
+
}];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
- (void)connectToCurrentCandidateLocked {
|
|
242
|
+
if (_currentEndpointIndex >= _candidateEndpoints.count) {
|
|
243
|
+
_connecting = NO;
|
|
244
|
+
[self tearDownConnectionLocked];
|
|
245
|
+
[self scheduleReconnectLocked];
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
JCORESisEndpoint *endpoint = _candidateEndpoints[_currentEndpointIndex];
|
|
249
|
+
[self connectToEndpoint:endpoint];
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
- (void)advanceToNextCandidateAfterFailureOfEndpoint:(JCORESisEndpoint *)failedEndpoint {
|
|
253
|
+
if (failedEndpoint.host.length > 0 && failedEndpoint.port > 0) {
|
|
254
|
+
NSString *ipPort = [NSString stringWithFormat:@"%@:%u", failedEndpoint.host, failedEndpoint.port];
|
|
255
|
+
[[JCOREConfiguration shared] addFailedIp:ipPort];
|
|
256
|
+
}
|
|
257
|
+
[self tearDownConnectionLocked];
|
|
258
|
+
|
|
259
|
+
_currentEndpointIndex++;
|
|
260
|
+
if (_currentEndpointIndex < _candidateEndpoints.count) {
|
|
261
|
+
_connecting = YES;
|
|
262
|
+
[self connectToCurrentCandidateLocked];
|
|
263
|
+
} else {
|
|
264
|
+
_connecting = NO;
|
|
265
|
+
[self scheduleReconnectLocked];
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
- (void)connectToEndpoint:(JCORESisEndpoint *)endpoint {
|
|
270
|
+
[self tearDownConnectionLocked];
|
|
271
|
+
_connecting = YES;
|
|
272
|
+
|
|
273
|
+
const char *hostStr = endpoint.host.UTF8String;
|
|
274
|
+
NSString *portString = [NSString stringWithFormat:@"%u", endpoint.port];
|
|
275
|
+
const char *portStr = portString.UTF8String;
|
|
276
|
+
if (hostStr == NULL || portStr == NULL) {
|
|
277
|
+
[self advanceToNextCandidateAfterFailureOfEndpoint:endpoint];
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
nw_endpoint_t nwEndpoint = nw_endpoint_create_host(hostStr, portStr);
|
|
282
|
+
nw_parameters_configure_protocol_block_t tlsConfig = endpoint.useSSL
|
|
283
|
+
? NW_PARAMETERS_DEFAULT_CONFIGURATION
|
|
284
|
+
: NW_PARAMETERS_DISABLE_PROTOCOL;
|
|
285
|
+
nw_parameters_t parameters = nw_parameters_create_secure_tcp(tlsConfig, NW_PARAMETERS_DEFAULT_CONFIGURATION);
|
|
286
|
+
nw_connection_t connection = nw_connection_create(nwEndpoint, parameters);
|
|
287
|
+
_connection = connection;
|
|
288
|
+
nw_connection_set_queue(connection, _sessionQueue);
|
|
289
|
+
|
|
290
|
+
[self startConnectTimeoutTimerLockedForConnection:connection endpoint:endpoint];
|
|
291
|
+
|
|
292
|
+
__weak typeof(self) weakSelf = self;
|
|
293
|
+
nw_connection_set_state_changed_handler(connection, ^(nw_connection_state_t state, nw_error_t error) {
|
|
294
|
+
(void)error;
|
|
295
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
296
|
+
if (!strongSelf || strongSelf->_connection != connection) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (state == nw_connection_state_ready) {
|
|
300
|
+
[strongSelf cancelConnectTimeoutTimerLocked];
|
|
301
|
+
strongSelf->_connecting = NO;
|
|
302
|
+
strongSelf->_connected = YES;
|
|
303
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidSetupNotification userInfo:nil];
|
|
304
|
+
[strongSelf receiveLoopForConnection:connection];
|
|
305
|
+
[strongSelf performHandshakeLocked];
|
|
306
|
+
} else if (state == nw_connection_state_waiting || state == nw_connection_state_failed) {
|
|
307
|
+
BOOL wasConnected = strongSelf->_connected;
|
|
308
|
+
if (!wasConnected) {
|
|
309
|
+
[strongSelf advanceToNextCandidateAfterFailureOfEndpoint:endpoint];
|
|
310
|
+
} else {
|
|
311
|
+
strongSelf->_connecting = NO;
|
|
312
|
+
[strongSelf tearDownConnectionLocked];
|
|
313
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidCloseNotification userInfo:nil];
|
|
314
|
+
if (!strongSelf->_userDisconnected && ![JCOREConfiguration shared].pushStopped && !strongSelf->_connecting) {
|
|
315
|
+
[strongSelf scheduleReconnectLocked];
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
} else if (state == nw_connection_state_cancelled) {
|
|
319
|
+
BOOL wasConnected = strongSelf->_connected;
|
|
320
|
+
strongSelf->_connected = NO;
|
|
321
|
+
strongSelf->_loggedIn = NO;
|
|
322
|
+
[strongSelf stopHeartbeatLocked];
|
|
323
|
+
if (strongSelf->_inFlightRequests.count > 0) {
|
|
324
|
+
NSError *closeErr = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
325
|
+
code:6002
|
|
326
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Connection closed"}];
|
|
327
|
+
[strongSelf failAllInFlightRequestsLockedWithError:closeErr];
|
|
328
|
+
}
|
|
329
|
+
if (wasConnected && strongSelf->_connection == connection) {
|
|
330
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidCloseNotification userInfo:nil];
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
nw_connection_start(connection);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
- (void)startConnectTimeoutTimerLockedForConnection:(nw_connection_t)connection
|
|
339
|
+
endpoint:(JCORESisEndpoint *)endpoint {
|
|
340
|
+
[self cancelConnectTimeoutTimerLocked];
|
|
341
|
+
NSTimeInterval timeout = [JCOREConfiguration shared].connectTimeoutInterval;
|
|
342
|
+
if (timeout <= 0) {
|
|
343
|
+
timeout = (_candidateEndpoints.count > 1) ? 1.5 : 5.0;
|
|
344
|
+
} else if (_candidateEndpoints.count > 1 && timeout > 1.5) {
|
|
345
|
+
timeout = 1.5;
|
|
346
|
+
}
|
|
347
|
+
uint64_t timeoutNs = (uint64_t)(timeout * (double)NSEC_PER_SEC);
|
|
348
|
+
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _sessionQueue);
|
|
349
|
+
dispatch_source_set_timer(timer,
|
|
350
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeoutNs),
|
|
351
|
+
DISPATCH_TIME_FOREVER,
|
|
352
|
+
(uint64_t)(0.05 * NSEC_PER_SEC));
|
|
353
|
+
__weak typeof(self) weakSelf = self;
|
|
354
|
+
dispatch_source_set_event_handler(timer, ^{
|
|
355
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
356
|
+
if (!strongSelf || strongSelf->_connection != connection || strongSelf->_connected) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
[strongSelf advanceToNextCandidateAfterFailureOfEndpoint:endpoint];
|
|
360
|
+
});
|
|
361
|
+
_connectTimeoutTimer = timer;
|
|
362
|
+
dispatch_resume(timer);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
- (void)cancelConnectTimeoutTimerLocked {
|
|
366
|
+
if (_connectTimeoutTimer != nil) {
|
|
367
|
+
dispatch_source_cancel(_connectTimeoutTimer);
|
|
368
|
+
_connectTimeoutTimer = nil;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
- (void)scheduleReconnectLocked {
|
|
373
|
+
[self cancelReconnectTimerLocked];
|
|
374
|
+
if (_userDisconnected || [JCOREConfiguration shared].pushStopped || [JCOREConfiguration shared].appKey.length == 0) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
NSTimeInterval base = [JCOREConfiguration shared].reconnectBaseInterval;
|
|
378
|
+
if (base <= 0) {
|
|
379
|
+
base = 3.0;
|
|
380
|
+
}
|
|
381
|
+
double multiplier = pow(2.0, (double)MIN(_reconnectAttempt, (NSUInteger)6));
|
|
382
|
+
NSTimeInterval delay = MIN(base * multiplier, 120.0);
|
|
383
|
+
_reconnectAttempt++;
|
|
384
|
+
|
|
385
|
+
uint64_t delayNs = (uint64_t)(delay * (double)NSEC_PER_SEC);
|
|
386
|
+
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _sessionQueue);
|
|
387
|
+
dispatch_source_set_timer(timer,
|
|
388
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)delayNs),
|
|
389
|
+
DISPATCH_TIME_FOREVER,
|
|
390
|
+
(uint64_t)(0.05 * NSEC_PER_SEC));
|
|
391
|
+
__weak typeof(self) weakSelf = self;
|
|
392
|
+
dispatch_source_set_event_handler(timer, ^{
|
|
393
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
394
|
+
if (!strongSelf) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
strongSelf->_reconnectTimer = nil;
|
|
398
|
+
if (!strongSelf->_userDisconnected && !strongSelf->_connected && !strongSelf->_connecting) {
|
|
399
|
+
[strongSelf startLockedForceReconnect:NO];
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
_reconnectTimer = timer;
|
|
403
|
+
dispatch_resume(timer);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
- (void)cancelReconnectTimerLocked {
|
|
407
|
+
if (_reconnectTimer != nil) {
|
|
408
|
+
dispatch_source_cancel(_reconnectTimer);
|
|
409
|
+
_reconnectTimer = nil;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
- (void)performHandshakeLocked {
|
|
414
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
415
|
+
if (config.uid == 0 || config.password.length == 0 || config.registrationID.length == 0) {
|
|
416
|
+
[self sendRegisterRequestLocked];
|
|
417
|
+
} else {
|
|
418
|
+
// Registered Device Fast-Login: skip Register (cmd=0) and send Login (cmd=1) directly
|
|
419
|
+
[self sendLoginRequestLocked];
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
- (void)sendRegisterRequestLocked {
|
|
424
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
425
|
+
NSString *bundleId = [config bundleIdentifierString];
|
|
426
|
+
NSData *regBody = [JCOREWireProtocol buildRegisterPayloadWithAppKey:config.appKey ?: @""
|
|
427
|
+
channel:config.channel
|
|
428
|
+
bundleIdHash:bundleId];
|
|
429
|
+
nw_connection_t activeConnection = _connection;
|
|
430
|
+
__weak typeof(self) weakSelf = self;
|
|
431
|
+
[self sendRawCommandLocked:JCOREWireCommandRegister
|
|
432
|
+
version:30
|
|
433
|
+
bodyData:regBody
|
|
434
|
+
completion:^(JCOREWireFrame *responseFrame, NSError *error) {
|
|
435
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
436
|
+
if (!strongSelf || strongSelf->_connection != activeConnection) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
JCORERegisterResponse *parsed = [JCOREWireProtocol parseRegisterResponse:responseFrame];
|
|
440
|
+
if (error == nil && parsed != nil && parsed.statusCode == 0 && parsed.uid > 0 && parsed.registrationID.length > 0) {
|
|
441
|
+
[config updateRegistrationWithUid:parsed.uid
|
|
442
|
+
password:parsed.password ?: @""
|
|
443
|
+
registrationID:parsed.registrationID
|
|
444
|
+
deviceID:parsed.deviceID];
|
|
445
|
+
[JCOREConfiguration logInfo:[NSString stringWithFormat:@"TCP register success uid=%llu registrationId=%@",
|
|
446
|
+
parsed.uid, parsed.registrationID]];
|
|
447
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidRegisterNotification
|
|
448
|
+
userInfo:@{
|
|
449
|
+
@"registrationID": parsed.registrationID,
|
|
450
|
+
@"uid": @(parsed.uid),
|
|
451
|
+
}];
|
|
452
|
+
[strongSelf sendLoginRequestLocked];
|
|
453
|
+
} else {
|
|
454
|
+
uint16_t errCode = parsed != nil ? parsed.statusCode : 1011;
|
|
455
|
+
[JCOREConfiguration logWarn:[NSString stringWithFormat:@"TCP register failed code=%u", errCode]];
|
|
456
|
+
[strongSelf postNotificationOnMain:kJPFNetworkFailedRegisterNotification
|
|
457
|
+
userInfo:@{@"code": @(errCode)}];
|
|
458
|
+
JCORESisEndpoint *currentEndpoint = (strongSelf->_currentEndpointIndex < strongSelf->_candidateEndpoints.count)
|
|
459
|
+
? strongSelf->_candidateEndpoints[strongSelf->_currentEndpointIndex]
|
|
460
|
+
: nil;
|
|
461
|
+
[strongSelf advanceToNextCandidateAfterFailureOfEndpoint:currentEndpoint];
|
|
462
|
+
}
|
|
463
|
+
}];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
- (void)sendLoginRequestLocked {
|
|
467
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
468
|
+
NSData *loginBody = [JCOREWireProtocol buildLoginPayloadWithPassword:config.password ?: @""
|
|
469
|
+
appKey:config.appKey ?: @""];
|
|
470
|
+
nw_connection_t activeConnection = _connection;
|
|
471
|
+
__weak typeof(self) weakSelf = self;
|
|
472
|
+
[self sendRawCommandLocked:JCOREWireCommandLogin
|
|
473
|
+
version:27
|
|
474
|
+
bodyData:loginBody
|
|
475
|
+
completion:^(JCOREWireFrame *responseFrame, NSError *error) {
|
|
476
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
477
|
+
if (!strongSelf || strongSelf->_connection != activeConnection) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
JCORESisEndpoint *currentEndpoint = (strongSelf->_currentEndpointIndex < strongSelf->_candidateEndpoints.count)
|
|
481
|
+
? strongSelf->_candidateEndpoints[strongSelf->_currentEndpointIndex]
|
|
482
|
+
: nil;
|
|
483
|
+
if (error != nil || responseFrame == nil) {
|
|
484
|
+
[strongSelf advanceToNextCandidateAfterFailureOfEndpoint:currentEndpoint];
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
JCORELoginResponse *login = [JCOREWireProtocol parseLoginResponse:responseFrame];
|
|
488
|
+
if (login != nil && login.statusCode == 108) {
|
|
489
|
+
// Status 108: uid unregistered/invalid on server -> clear credentials and re-register immediately
|
|
490
|
+
[config resetRegistration];
|
|
491
|
+
[strongSelf sendRegisterRequestLocked];
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
if (login != nil && login.statusCode == 1012) {
|
|
495
|
+
// Status 1012: server requests SIS cache reset and re-resolution
|
|
496
|
+
[config resetSisCache];
|
|
497
|
+
[strongSelf startLockedForceReconnect:YES];
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
if (login != nil && login.statusCode != 0) {
|
|
501
|
+
[strongSelf postNotificationOnMain:kJPFServiceErrorNotification
|
|
502
|
+
userInfo:@{@"code": @(login.statusCode)}];
|
|
503
|
+
[strongSelf advanceToNextCandidateAfterFailureOfEndpoint:currentEndpoint];
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (login != nil) {
|
|
508
|
+
strongSelf->_sessionId = login.sessionId;
|
|
509
|
+
strongSelf->_serverVersion = login.serverVersion;
|
|
510
|
+
strongSelf->_serverTimestamp = login.serverTimestamp;
|
|
511
|
+
}
|
|
512
|
+
strongSelf->_loggedIn = YES;
|
|
513
|
+
strongSelf->_reconnectAttempt = 0;
|
|
514
|
+
[config clearFailedIps];
|
|
515
|
+
[JCOREConfiguration logInfo:[NSString stringWithFormat:@"TCP login success uid=%llu sid=%u registrationId=%@",
|
|
516
|
+
config.uid,
|
|
517
|
+
strongSelf->_sessionId,
|
|
518
|
+
config.registrationID ?: @""]];
|
|
519
|
+
[strongSelf startHeartbeatLocked];
|
|
520
|
+
[strongSelf reportDeviceTokenLocked];
|
|
521
|
+
[strongSelf reportVoipTokenLocked];
|
|
522
|
+
[strongSelf flushQueuedRequestsLocked];
|
|
523
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidLoginNotification
|
|
524
|
+
userInfo:@{
|
|
525
|
+
@"registrationID": config.registrationID ?: @"",
|
|
526
|
+
@"sessionId": @(strongSelf->_sessionId),
|
|
527
|
+
@"serverVersion": @(strongSelf->_serverVersion),
|
|
528
|
+
@"serverTimestamp": @(strongSelf->_serverTimestamp),
|
|
529
|
+
}];
|
|
530
|
+
}];
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
- (void)startHeartbeatLocked {
|
|
534
|
+
[self stopHeartbeatLocked];
|
|
535
|
+
NSTimeInterval interval = [JCOREConfiguration shared].heartbeatInterval;
|
|
536
|
+
if (interval <= 0) {
|
|
537
|
+
interval = 240.0;
|
|
538
|
+
}
|
|
539
|
+
uint64_t intervalNs = (uint64_t)(interval * (double)NSEC_PER_SEC);
|
|
540
|
+
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _sessionQueue);
|
|
541
|
+
dispatch_source_set_timer(timer,
|
|
542
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)intervalNs),
|
|
543
|
+
intervalNs,
|
|
544
|
+
(uint64_t)(1 * NSEC_PER_SEC));
|
|
545
|
+
__weak typeof(self) weakSelf = self;
|
|
546
|
+
dispatch_source_set_event_handler(timer, ^{
|
|
547
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
548
|
+
if (!strongSelf || !strongSelf->_connected || !strongSelf->_loggedIn) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
NSData *hb = [JCOREWireProtocol buildHeartbeatPayloadWithPushStopped:[JCOREConfiguration shared].pushStopped];
|
|
552
|
+
[strongSelf sendRawCommandLocked:JCOREWireCommandHeartbeat version:8 bodyData:hb completion:nil];
|
|
553
|
+
});
|
|
554
|
+
_heartbeatTimer = timer;
|
|
555
|
+
dispatch_resume(timer);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
- (void)stopHeartbeatLocked {
|
|
559
|
+
if (_heartbeatTimer != nil) {
|
|
560
|
+
dispatch_source_cancel(_heartbeatTimer);
|
|
561
|
+
_heartbeatTimer = nil;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
- (void)sendHeartbeatNowWithCompletion:(JCORETcpResponseHandler)completion {
|
|
566
|
+
dispatch_async(_sessionQueue, ^{
|
|
567
|
+
NSData *hb = [JCOREWireProtocol buildHeartbeatPayloadWithPushStopped:[JCOREConfiguration shared].pushStopped];
|
|
568
|
+
[self sendRawCommandLocked:JCOREWireCommandHeartbeat version:8 bodyData:hb completion:completion];
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
- (void)receiveLoopForConnection:(nw_connection_t)connection {
|
|
573
|
+
__weak typeof(self) weakSelf = self;
|
|
574
|
+
nw_connection_receive(connection, 1, 65536, ^(dispatch_data_t content, nw_content_context_t context, bool is_complete, nw_error_t error) {
|
|
575
|
+
(void)context;
|
|
576
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
577
|
+
if (!strongSelf || strongSelf->_connection != connection) {
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
if (content != nil) {
|
|
581
|
+
NSData *chunk = (NSData *)content;
|
|
582
|
+
if (chunk.length > 0) {
|
|
583
|
+
[strongSelf->_receiveBuffer appendData:chunk];
|
|
584
|
+
NSArray<JCOREWireFrame *> *frames = [JCOREWireProtocol decodeServerFramesFromStreamBuffer:strongSelf->_receiveBuffer
|
|
585
|
+
defaultUid:[JCOREConfiguration shared].uid];
|
|
586
|
+
for (JCOREWireFrame *frame in frames) {
|
|
587
|
+
[strongSelf handleDecodedFrameLocked:frame];
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (error == nil && !is_complete) {
|
|
592
|
+
[strongSelf receiveLoopForConnection:connection];
|
|
593
|
+
} else if (is_complete || error != nil) {
|
|
594
|
+
BOOL wasConnected = strongSelf->_connected;
|
|
595
|
+
strongSelf->_connecting = NO;
|
|
596
|
+
strongSelf->_connected = NO;
|
|
597
|
+
strongSelf->_loggedIn = NO;
|
|
598
|
+
[strongSelf stopHeartbeatLocked];
|
|
599
|
+
if (strongSelf->_inFlightRequests.count > 0) {
|
|
600
|
+
NSError *closeErr = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
601
|
+
code:6002
|
|
602
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Connection closed"}];
|
|
603
|
+
[strongSelf failAllInFlightRequestsLockedWithError:closeErr];
|
|
604
|
+
}
|
|
605
|
+
if (wasConnected && strongSelf->_connection == connection) {
|
|
606
|
+
[strongSelf postNotificationOnMain:kJPFNetworkDidCloseNotification userInfo:nil];
|
|
607
|
+
if (!strongSelf->_userDisconnected && ![JCOREConfiguration shared].pushStopped && !strongSelf->_connecting) {
|
|
608
|
+
[strongSelf scheduleReconnectLocked];
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
- (void)handleDecodedFrameLocked:(JCOREWireFrame *)frame {
|
|
616
|
+
if (frame.command == JCOREWireCommandPushMessage) {
|
|
617
|
+
JCOREPushEnvelope *envelope = [JCOREWireProtocol parsePushEnvelope:frame];
|
|
618
|
+
if (envelope != nil) {
|
|
619
|
+
[JCOREConfiguration logInfo:[NSString stringWithFormat:@"TCP push message received msgType=%u msgId=%llu",
|
|
620
|
+
envelope.messageType, envelope.messageId]];
|
|
621
|
+
[self sendReceiptLockedForMessageType:envelope.messageType
|
|
622
|
+
messageId:envelope.messageId
|
|
623
|
+
requestId:frame.requestId];
|
|
624
|
+
NSMutableDictionary *payload = [NSMutableDictionary dictionary];
|
|
625
|
+
if ([envelope.jsonPayload isKindOfClass:[NSDictionary class]]) {
|
|
626
|
+
[payload addEntriesFromDictionary:envelope.jsonPayload];
|
|
627
|
+
}
|
|
628
|
+
if (payload[@"_j_msgid"] == nil) {
|
|
629
|
+
payload[@"_j_msgid"] = @(envelope.messageId);
|
|
630
|
+
}
|
|
631
|
+
if (payload[@"content"] == nil && envelope.content != nil) {
|
|
632
|
+
payload[@"content"] = envelope.content;
|
|
633
|
+
}
|
|
634
|
+
[self postNotificationOnMain:kJPFNetworkDidReceiveMessageNotification userInfo:[payload copy]];
|
|
635
|
+
}
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
if (frame.command == JCOREWireCommandCtrlCommand) {
|
|
640
|
+
JCORECtrlEnvelope *ctrl = [JCOREWireProtocol parseCtrlEnvelope:frame];
|
|
641
|
+
if (ctrl != nil) {
|
|
642
|
+
NSData *ackBody = [JCOREWireProtocol buildCtrlAckPayloadWithStatusCode:0 requestId:ctrl.requestId];
|
|
643
|
+
[self sendPacketWithExplicitRequestIdLocked:(frame.requestId != 0 ? frame.requestId : [[JCOREConfiguration shared] nextRequestId])
|
|
644
|
+
command:JCOREWireCommandCtrlCommand
|
|
645
|
+
version:1
|
|
646
|
+
bodyData:ackBody];
|
|
647
|
+
NSMutableDictionary *info = [NSMutableDictionary dictionary];
|
|
648
|
+
info[@"requestId"] = @(ctrl.requestId);
|
|
649
|
+
if (ctrl.jsonPayload != nil) {
|
|
650
|
+
info[@"payload"] = ctrl.jsonPayload;
|
|
651
|
+
}
|
|
652
|
+
[self postNotificationOnMain:@"kJPFNetworkDidReceiveCtrlCommandNotification" userInfo:info];
|
|
653
|
+
}
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
NSNumber *key = @(frame.requestId);
|
|
658
|
+
JCOREInFlightRequest *inFlight = _inFlightRequests[key];
|
|
659
|
+
if (inFlight != nil) {
|
|
660
|
+
[inFlight cancelTimers];
|
|
661
|
+
[_inFlightRequests removeObjectForKey:key];
|
|
662
|
+
if (inFlight.completion != nil) {
|
|
663
|
+
inFlight.completion(frame, nil);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
- (void)reportDeviceTokenIfNeeded {
|
|
669
|
+
dispatch_async(_sessionQueue, ^{
|
|
670
|
+
[self reportDeviceTokenLocked];
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
- (void)reportDeviceTokenLocked {
|
|
675
|
+
NSString *tokenHex = [JCOREConfiguration shared].deviceTokenHex;
|
|
676
|
+
if (tokenHex.length == 0) {
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
if (!_connected || !_loggedIn) {
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
if ([_lastReportedDeviceTokenHex isEqualToString:tokenHex]) {
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
685
|
+
_lastReportedDeviceTokenHex = [tokenHex copy];
|
|
686
|
+
NSData *body = [JCOREWireProtocol buildDeviceTokenPayloadWithTokenHex:tokenHex];
|
|
687
|
+
[self sendRawCommandLocked:JCOREWireCommandDeviceToken version:3 bodyData:body completion:nil];
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
- (void)reportVoipTokenIfNeeded {
|
|
691
|
+
dispatch_async(_sessionQueue, ^{
|
|
692
|
+
[self reportVoipTokenLocked];
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
- (void)reportVoipTokenLocked {
|
|
697
|
+
NSString *voipHex = [JCOREConfiguration shared].voipTokenHex;
|
|
698
|
+
if (voipHex.length == 0) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
if (!_connected || !_loggedIn) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
if ([_lastReportedVoipTokenHex isEqualToString:voipHex]) {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
_lastReportedVoipTokenHex = [voipHex copy];
|
|
708
|
+
NSData *body = [JCOREWireProtocol buildVoipTokenPayloadWithTokenHex:voipHex];
|
|
709
|
+
[self sendRawCommandLocked:JCOREWireCommandVoipToken version:2 bodyData:body completion:nil];
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
- (void)sendReceiptForMessageType:(uint8_t)messageType messageId:(uint64_t)messageId {
|
|
713
|
+
dispatch_async(_sessionQueue, ^{
|
|
714
|
+
[self sendReceiptLockedForMessageType:messageType messageId:messageId requestId:0];
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
- (void)sendReceiptLockedForMessageType:(uint8_t)messageType
|
|
719
|
+
messageId:(uint64_t)messageId
|
|
720
|
+
requestId:(uint16_t)requestId {
|
|
721
|
+
if (!_connected || messageId == 0) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
NSData *body = [JCOREWireProtocol buildMessageAckPayloadWithMessageType:messageType messageId:messageId];
|
|
725
|
+
uint16_t rid = (requestId != 0) ? requestId : [[JCOREConfiguration shared] nextRequestId];
|
|
726
|
+
[self sendPacketWithExplicitRequestIdLocked:rid
|
|
727
|
+
command:JCOREWireCommandMessageAck
|
|
728
|
+
version:3
|
|
729
|
+
bodyData:body];
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
- (void)sendPacketWithExplicitRequestIdLocked:(uint16_t)rid
|
|
733
|
+
command:(uint8_t)command
|
|
734
|
+
version:(uint8_t)version
|
|
735
|
+
bodyData:(NSData *)bodyData {
|
|
736
|
+
if (!_connected || _connection == nil) {
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
740
|
+
NSData *packet = [JCOREWireProtocol encodeFrameWithCommand:command
|
|
741
|
+
version:version
|
|
742
|
+
requestId:rid
|
|
743
|
+
sessionId:_sessionId
|
|
744
|
+
uid:config.uid
|
|
745
|
+
bodyData:bodyData];
|
|
746
|
+
if (packet.length == 0) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
dispatch_data_t dispatchPacket = dispatch_data_create(packet.bytes,
|
|
750
|
+
packet.length,
|
|
751
|
+
_sessionQueue,
|
|
752
|
+
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
|
753
|
+
nw_connection_send(_connection, dispatchPacket, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t error) {
|
|
754
|
+
(void)error;
|
|
755
|
+
});
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
- (void)sendCommand:(uint8_t)command
|
|
759
|
+
version:(uint8_t)version
|
|
760
|
+
bodyData:(NSData *)bodyData
|
|
761
|
+
completion:(JCORETcpResponseHandler)completion {
|
|
762
|
+
dispatch_async(_sessionQueue, ^{
|
|
763
|
+
if (command != JCOREWireCommandRegister &&
|
|
764
|
+
command != JCOREWireCommandLogin &&
|
|
765
|
+
(!self->_connected || !self->_loggedIn)) {
|
|
766
|
+
JCOREQueuedWireRequest *queued = [[JCOREQueuedWireRequest alloc] init];
|
|
767
|
+
queued.command = command;
|
|
768
|
+
queued.version = version;
|
|
769
|
+
queued.bodyData = bodyData ?: [NSData data];
|
|
770
|
+
queued.completion = completion;
|
|
771
|
+
[self->_queuedRequests addObject:queued];
|
|
772
|
+
if (!self->_connected && !self->_connecting && !self->_userDisconnected) {
|
|
773
|
+
[self startLockedForceReconnect:NO];
|
|
774
|
+
}
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
[self sendRawCommandLocked:command version:version bodyData:bodyData completion:completion];
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
- (void)flushQueuedRequestsLocked {
|
|
782
|
+
if (_queuedRequests.count == 0) {
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
NSArray<JCOREQueuedWireRequest *> *toSend = [_queuedRequests copy];
|
|
786
|
+
[_queuedRequests removeAllObjects];
|
|
787
|
+
for (JCOREQueuedWireRequest *item in toSend) {
|
|
788
|
+
[self sendRawCommandLocked:item.command
|
|
789
|
+
version:item.version
|
|
790
|
+
bodyData:item.bodyData
|
|
791
|
+
completion:item.completion];
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
- (void)sendRawCommandLocked:(uint8_t)command
|
|
796
|
+
version:(uint8_t)version
|
|
797
|
+
bodyData:(NSData *)bodyData
|
|
798
|
+
completion:(JCORETcpResponseHandler)completion {
|
|
799
|
+
JCOREConfiguration *config = [JCOREConfiguration shared];
|
|
800
|
+
if (!_connected || _connection == nil) {
|
|
801
|
+
if (completion != nil) {
|
|
802
|
+
NSError *err = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
803
|
+
code:6002
|
|
804
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Not connected"}];
|
|
805
|
+
completion(nil, err);
|
|
806
|
+
}
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
uint16_t rid = [config nextRequestId];
|
|
811
|
+
uint64_t packetUid = (command == JCOREWireCommandRegister) ? 0ULL : config.uid;
|
|
812
|
+
NSData *packet = [JCOREWireProtocol encodeFrameWithCommand:command
|
|
813
|
+
version:version
|
|
814
|
+
requestId:rid
|
|
815
|
+
sessionId:_sessionId
|
|
816
|
+
uid:packetUid
|
|
817
|
+
bodyData:bodyData];
|
|
818
|
+
if (packet.length == 0) {
|
|
819
|
+
if (completion != nil) {
|
|
820
|
+
NSError *err = [NSError errorWithDomain:@"cn.jiguang.jcore" code:-1002 userInfo:nil];
|
|
821
|
+
completion(nil, err);
|
|
822
|
+
}
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
if (completion != nil) {
|
|
827
|
+
NSNumber *ridKey = @(rid);
|
|
828
|
+
JCOREInFlightRequest *inFlight = [[JCOREInFlightRequest alloc] init];
|
|
829
|
+
inFlight.requestId = rid;
|
|
830
|
+
inFlight.command = command;
|
|
831
|
+
inFlight.version = version;
|
|
832
|
+
inFlight.packetData = packet;
|
|
833
|
+
inFlight.completion = completion;
|
|
834
|
+
|
|
835
|
+
NSTimeInterval timeoutSec = config.requestTimeoutInterval > 0 ? config.requestTimeoutInterval : 20.0;
|
|
836
|
+
NSTimeInterval resendSec = config.requestResendInterval > 0 ? config.requestResendInterval : 10.0;
|
|
837
|
+
|
|
838
|
+
if (resendSec > 0 && resendSec < timeoutSec) {
|
|
839
|
+
uint64_t resendNs = (uint64_t)(resendSec * (double)NSEC_PER_SEC);
|
|
840
|
+
dispatch_source_t rTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _sessionQueue);
|
|
841
|
+
dispatch_source_set_timer(rTimer,
|
|
842
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)resendNs),
|
|
843
|
+
DISPATCH_TIME_FOREVER,
|
|
844
|
+
(uint64_t)(0.05 * NSEC_PER_SEC));
|
|
845
|
+
__weak typeof(self) weakSelf = self;
|
|
846
|
+
dispatch_source_set_event_handler(rTimer, ^{
|
|
847
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
848
|
+
if (!strongSelf) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
JCOREInFlightRequest *req = strongSelf->_inFlightRequests[ridKey];
|
|
852
|
+
if (req != nil && strongSelf->_connected && strongSelf->_connection != nil) {
|
|
853
|
+
dispatch_data_t resendData = dispatch_data_create(req.packetData.bytes,
|
|
854
|
+
req.packetData.length,
|
|
855
|
+
strongSelf->_sessionQueue,
|
|
856
|
+
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
|
857
|
+
nw_connection_send(strongSelf->_connection, resendData, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t error) {
|
|
858
|
+
(void)error;
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
inFlight.resendTimer = rTimer;
|
|
863
|
+
dispatch_resume(rTimer);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
uint64_t timeoutNs = (uint64_t)(timeoutSec * (double)NSEC_PER_SEC);
|
|
867
|
+
dispatch_source_t tTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _sessionQueue);
|
|
868
|
+
dispatch_source_set_timer(tTimer,
|
|
869
|
+
dispatch_time(DISPATCH_TIME_NOW, (int64_t)timeoutNs),
|
|
870
|
+
DISPATCH_TIME_FOREVER,
|
|
871
|
+
(uint64_t)(0.05 * NSEC_PER_SEC));
|
|
872
|
+
__weak typeof(self) weakSelf = self;
|
|
873
|
+
dispatch_source_set_event_handler(tTimer, ^{
|
|
874
|
+
__strong typeof(weakSelf) strongSelf = weakSelf;
|
|
875
|
+
if (!strongSelf) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
JCOREInFlightRequest *timedOut = strongSelf->_inFlightRequests[ridKey];
|
|
879
|
+
if (timedOut != nil) {
|
|
880
|
+
[timedOut cancelTimers];
|
|
881
|
+
[strongSelf->_inFlightRequests removeObjectForKey:ridKey];
|
|
882
|
+
if (timedOut.completion != nil) {
|
|
883
|
+
NSError *timeoutErr = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
884
|
+
code:6002
|
|
885
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Request timed out"}];
|
|
886
|
+
timedOut.completion(nil, timeoutErr);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
inFlight.timeoutTimer = tTimer;
|
|
891
|
+
dispatch_resume(tTimer);
|
|
892
|
+
|
|
893
|
+
_inFlightRequests[ridKey] = inFlight;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
dispatch_data_t dispatchPacket = dispatch_data_create(packet.bytes,
|
|
897
|
+
packet.length,
|
|
898
|
+
_sessionQueue,
|
|
899
|
+
DISPATCH_DATA_DESTRUCTOR_DEFAULT);
|
|
900
|
+
nw_connection_send(_connection, dispatchPacket, NW_CONNECTION_DEFAULT_MESSAGE_CONTEXT, true, ^(nw_error_t error) {
|
|
901
|
+
(void)error;
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
- (void)failAllInFlightRequestsLockedWithError:(NSError *)error {
|
|
906
|
+
NSDictionary<NSNumber *, JCOREInFlightRequest *> *snapshot = [_inFlightRequests copy];
|
|
907
|
+
[_inFlightRequests removeAllObjects];
|
|
908
|
+
[snapshot enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, JCOREInFlightRequest *req, BOOL *stop) {
|
|
909
|
+
(void)key;
|
|
910
|
+
(void)stop;
|
|
911
|
+
[req cancelTimers];
|
|
912
|
+
if (req.completion != nil) {
|
|
913
|
+
req.completion(nil, error);
|
|
914
|
+
}
|
|
915
|
+
}];
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
- (void)tearDownConnectionLocked {
|
|
919
|
+
[self cancelConnectTimeoutTimerLocked];
|
|
920
|
+
[self stopHeartbeatLocked];
|
|
921
|
+
if (_connection != nil) {
|
|
922
|
+
nw_connection_cancel(_connection);
|
|
923
|
+
_connection = nil;
|
|
924
|
+
}
|
|
925
|
+
[_receiveBuffer setLength:0];
|
|
926
|
+
_connected = NO;
|
|
927
|
+
_loggedIn = NO;
|
|
928
|
+
if (_inFlightRequests.count > 0) {
|
|
929
|
+
NSError *err = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
930
|
+
code:6002
|
|
931
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Connection closed"}];
|
|
932
|
+
[self failAllInFlightRequestsLockedWithError:err];
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
- (void)disconnect {
|
|
937
|
+
dispatch_async(_sessionQueue, ^{
|
|
938
|
+
self->_userDisconnected = YES;
|
|
939
|
+
[self cancelReconnectTimerLocked];
|
|
940
|
+
BOOL wasConnected = self->_connected;
|
|
941
|
+
self->_connecting = NO;
|
|
942
|
+
[self tearDownConnectionLocked];
|
|
943
|
+
NSError *err = [NSError errorWithDomain:@"cn.jiguang.jpush"
|
|
944
|
+
code:6002
|
|
945
|
+
userInfo:@{NSLocalizedDescriptionKey: @"Disconnected"}];
|
|
946
|
+
[self failAllInFlightRequestsLockedWithError:err];
|
|
947
|
+
if (wasConnected) {
|
|
948
|
+
[self postNotificationOnMain:kJPFNetworkDidCloseNotification userInfo:nil];
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
@end
|
|
954
|
+
|
|
955
|
+
@implementation JCORETcpClient
|
|
956
|
+
@end
|