2
0

WFCCNetworkService.mm 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. //
  2. // WFCCNetworkService.mm
  3. // WFChatClient
  4. //
  5. // Created by heavyrain on 2017/11/5.
  6. // Copyright © 2017年 WildFireChat. All rights reserved.
  7. //
  8. #include "WFCCNetworkService.h"
  9. #import <UIKit/UIKit.h>
  10. #import <SystemConfiguration/SCNetworkReachability.h>
  11. #import <sys/xattr.h>
  12. #import <CommonCrypto/CommonDigest.h>
  13. #import "app_callback.h"
  14. #include <mars/baseevent/base_logic.h>
  15. #include <mars/xlog/xlogger.h>
  16. #include <mars/xlog/xloggerbase.h>
  17. #include <mars/xlog/appender.h>
  18. #include <mars/proto/proto.h>
  19. #include <mars/stn/stn_logic.h>
  20. #include <list>
  21. #import "WFCCIMService.h"
  22. #import "WFCCNetworkStatus.h"
  23. #import "WFCCRecallMessageContent.h"
  24. const NSString *SDKVERSION = @"0.1";
  25. extern NSMutableArray* convertProtoMessageList(const std::list<mars::stn::TMessage> &messageList, BOOL reverse);
  26. NSString *kGroupInfoUpdated = @"kGroupInfoUpdated";
  27. NSString *kUserInfoUpdated = @"kUserInfoUpdated";
  28. NSString *kFriendListUpdated = @"kFriendListUpdated";
  29. NSString *kFriendRequestUpdated = @"kFriendRequestUpdated";
  30. NSString *kSettingUpdated = @"kSettingUpdated";
  31. NSString *kChannelInfoUpdated = @"kChannelInfoUpdated";
  32. @protocol RefreshGroupInfoDelegate <NSObject>
  33. - (void)onGroupInfoUpdated:(NSArray<WFCCGroupInfo *> *)updatedGroupInfo;
  34. @end
  35. @protocol RefreshChannelInfoDelegate <NSObject>
  36. - (void)onChannelInfoUpdated:(NSArray<WFCCChannelInfo *> *)updatedChannelInfo;
  37. @end
  38. @protocol RefreshUserInfoDelegate <NSObject>
  39. - (void)onUserInfoUpdated:(NSArray<WFCCUserInfo *> *)updatedUserInfo;
  40. @end
  41. @protocol RefreshFriendListDelegate <NSObject>
  42. - (void)onFriendListUpdated;
  43. @end
  44. @protocol RefreshFriendRequestDelegate <NSObject>
  45. - (void)onFriendRequestUpdated;
  46. @end
  47. @protocol RefreshSettingDelegate <NSObject>
  48. - (void)onSettingUpdated;
  49. @end
  50. class CSCB : public mars::stn::ConnectionStatusCallback {
  51. public:
  52. CSCB(id<ConnectionStatusDelegate> delegate) : m_delegate(delegate) {
  53. }
  54. void onConnectionStatusChanged(mars::stn::ConnectionStatus connectionStatus) {
  55. if (m_delegate) {
  56. [m_delegate onConnectionStatusChanged:(ConnectionStatus)connectionStatus];
  57. }
  58. }
  59. id<ConnectionStatusDelegate> m_delegate;
  60. };
  61. class RPCB : public mars::stn::ReceiveMessageCallback {
  62. public:
  63. RPCB(id<ReceiveMessageDelegate> delegate) : m_delegate(delegate) {}
  64. void onReceiveMessage(const std::list<mars::stn::TMessage> &messageList, bool hasMore) {
  65. if (m_delegate) {
  66. NSMutableArray *messages = convertProtoMessageList(messageList, NO);
  67. [m_delegate onReceiveMessage:messages hasMore:hasMore];
  68. }
  69. }
  70. void onRecallMessage(const std::string operatorId, long long messageUid) {
  71. if (m_delegate) {
  72. [m_delegate onRecallMessage:messageUid];
  73. }
  74. }
  75. id<ReceiveMessageDelegate> m_delegate;
  76. };
  77. WFCCUserInfo* convertUserInfo(const mars::stn::TUserInfo &tui) {
  78. WFCCUserInfo *userInfo = [[WFCCUserInfo alloc] init];
  79. userInfo.userId = [NSString stringWithUTF8String:tui.uid.c_str()];
  80. userInfo.name = [NSString stringWithUTF8String:tui.name.c_str()];
  81. userInfo.portrait = [NSString stringWithUTF8String:tui.portrait.c_str()];
  82. userInfo.displayName = [NSString stringWithUTF8String:tui.displayName.c_str()];
  83. userInfo.gender = tui.gender;
  84. userInfo.social = [NSString stringWithUTF8String:tui.social.c_str()];
  85. userInfo.mobile = [NSString stringWithUTF8String:tui.mobile.c_str()];
  86. userInfo.email = [NSString stringWithUTF8String:tui.email.c_str()];
  87. userInfo.address = [NSString stringWithUTF8String:tui.address.c_str()];
  88. userInfo.company = [NSString stringWithUTF8String:tui.company.c_str()];
  89. userInfo.social = [NSString stringWithUTF8String:tui.social.c_str()];
  90. userInfo.extra = [NSString stringWithUTF8String:tui.extra.c_str()];
  91. userInfo.updateDt = tui.updateDt;
  92. return userInfo;
  93. }
  94. NSArray<WFCCUserInfo *>* converUserInfos(const std::list<mars::stn::TUserInfo> &userInfoList) {
  95. NSMutableArray *out = [[NSMutableArray alloc] init];
  96. for (std::list<mars::stn::TUserInfo>::const_iterator it = userInfoList.begin(); it != userInfoList.end(); it++) {
  97. [out addObject:convertUserInfo(*it)];
  98. }
  99. return out;
  100. }
  101. WFCCGroupInfo* convertGroupInfo(const mars::stn::TGroupInfo &tgi) {
  102. WFCCGroupInfo *groupInfo = [[WFCCGroupInfo alloc] init];
  103. groupInfo.type = (WFCCGroupType)tgi.type;
  104. groupInfo.target = [NSString stringWithUTF8String:tgi.target.c_str()];
  105. groupInfo.name = [NSString stringWithUTF8String:tgi.name.c_str()];
  106. groupInfo.extra = [NSData dataWithBytes:tgi.extra.c_str() length:tgi.extra.length()];
  107. groupInfo.portrait = [NSString stringWithUTF8String:tgi.portrait.c_str()];
  108. groupInfo.owner = [NSString stringWithUTF8String:tgi.owner.c_str()];
  109. groupInfo.memberCount = tgi.memberCount;
  110. return groupInfo;
  111. }
  112. extern WFCCChannelInfo *convertProtoChannelInfo(const mars::stn::TChannelInfo &tci);
  113. NSArray<WFCCGroupInfo *>* convertGroupInfos(const std::list<mars::stn::TGroupInfo> &groupInfoList) {
  114. NSMutableArray *out = [[NSMutableArray alloc] init];
  115. for (std::list<mars::stn::TGroupInfo>::const_iterator it = groupInfoList.begin(); it != groupInfoList.end(); it++) {
  116. [out addObject:convertGroupInfo(*it)];
  117. }
  118. return out;
  119. }
  120. NSArray<WFCCChannelInfo *>* convertChannelInfos(const std::list<mars::stn::TChannelInfo> &channelInfoList) {
  121. NSMutableArray *out = [[NSMutableArray alloc] init];
  122. for (std::list<mars::stn::TChannelInfo>::const_iterator it = channelInfoList.begin(); it != channelInfoList.end(); it++) {
  123. [out addObject:convertProtoChannelInfo(*it)];
  124. }
  125. return out;
  126. }
  127. class GUCB : public mars::stn::GetUserInfoCallback {
  128. public:
  129. GUCB(id<RefreshUserInfoDelegate> delegate) : m_delegate(delegate) {}
  130. void onSuccess(const std::list<mars::stn::TUserInfo> &userInfoList) {
  131. if(m_delegate) {
  132. [m_delegate onUserInfoUpdated:converUserInfos(userInfoList)];
  133. }
  134. }
  135. void onFalure(int errorCode) {
  136. }
  137. id<RefreshUserInfoDelegate> m_delegate;
  138. };
  139. class GGCB : public mars::stn::GetGroupInfoCallback {
  140. public:
  141. GGCB(id<RefreshGroupInfoDelegate> delegate) : m_delegate(delegate) {}
  142. void onSuccess(const std::list<mars::stn::TGroupInfo> &groupInfoList) {
  143. if(m_delegate && !groupInfoList.empty()) {
  144. [m_delegate onGroupInfoUpdated:convertGroupInfos(groupInfoList)];
  145. }
  146. }
  147. void onFalure(int errorCode) {
  148. }
  149. id<RefreshGroupInfoDelegate> m_delegate;
  150. };
  151. class GCHCB : public mars::stn::GetChannelInfoCallback {
  152. public:
  153. GCHCB(id<RefreshChannelInfoDelegate> delegate) : m_delegate(delegate) {}
  154. void onSuccess(const std::list<mars::stn::TChannelInfo> &channelInfoList) {
  155. if(m_delegate && !channelInfoList.empty()) {
  156. [m_delegate onChannelInfoUpdated:convertChannelInfos(channelInfoList)];
  157. }
  158. }
  159. void onFalure(int errorCode) {
  160. }
  161. id<RefreshChannelInfoDelegate> m_delegate;
  162. };
  163. class GFLCB : public mars::stn::GetMyFriendsCallback {
  164. public:
  165. GFLCB(id<RefreshFriendListDelegate> delegate) : m_delegate(delegate) {}
  166. void onSuccess(std::list<std::string> friendIdList) {
  167. if(m_delegate && friendIdList.size() > 0) {
  168. [m_delegate onFriendListUpdated];
  169. }
  170. }
  171. void onFalure(int errorCode) {
  172. }
  173. id<RefreshFriendListDelegate> m_delegate;
  174. };
  175. class GFRCB : public mars::stn::GetFriendRequestCallback {
  176. public:
  177. GFRCB(id<RefreshFriendRequestDelegate> delegate) : m_delegate(delegate) {}
  178. void onSuccess(bool hasNewRequest) {
  179. if(m_delegate && hasNewRequest) {
  180. [m_delegate onFriendRequestUpdated];
  181. }
  182. }
  183. void onFalure(int errorCode) {
  184. }
  185. id<RefreshFriendRequestDelegate> m_delegate;
  186. };
  187. class GSCB : public mars::stn::GetSettingCallback {
  188. public:
  189. GSCB(id<RefreshSettingDelegate> delegate) : m_delegate(delegate) {}
  190. void onSuccess(bool hasNewRequest) {
  191. if(m_delegate && hasNewRequest) {
  192. [m_delegate onSettingUpdated];
  193. }
  194. }
  195. void onFalure(int errorCode) {
  196. }
  197. id<RefreshSettingDelegate> m_delegate;
  198. };
  199. @interface WFCCNetworkService () <ConnectionStatusDelegate, ReceiveMessageDelegate, RefreshUserInfoDelegate, RefreshGroupInfoDelegate, WFCCNetworkStatusDelegate, RefreshFriendListDelegate, RefreshFriendRequestDelegate, RefreshSettingDelegate, RefreshChannelInfoDelegate>
  200. @property(nonatomic, assign)ConnectionStatus currentConnectionStatus;
  201. @property (nonatomic, strong)NSString *userId;
  202. @property (nonatomic, strong)NSString *passwd;
  203. @property(nonatomic, strong)NSString *serverHost;
  204. @property(nonatomic, assign)int serverPort;
  205. @property(nonatomic, assign)UIBackgroundTaskIdentifier bgTaskId;
  206. @property(nonatomic, strong)NSTimer *forceConnectTimer;
  207. @property(nonatomic, strong)NSTimer *suspendTimer;
  208. @property(nonatomic, strong)NSTimer *endBgTaskTimer;
  209. @property(nonatomic, strong)NSString *backupDeviceToken;
  210. @property(nonatomic, strong)NSString *backupVoipDeviceToken;
  211. @property(nonatomic, assign)BOOL requestProxying;
  212. @property(nonatomic, strong) NSMutableArray *messageFilterList;
  213. - (void)reportEvent_OnForeground:(BOOL)isForeground;
  214. @property(nonatomic, assign)NSUInteger backgroudRunTime;
  215. @end
  216. @implementation WFCCNetworkService
  217. static WFCCNetworkService * sharedSingleton = nil;
  218. + (void)startLog {
  219. NSString* logPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingString:@"/log"];
  220. // set do not backup for logpath
  221. const char* attrName = "com.apple.MobileBackup";
  222. u_int8_t attrValue = 1;
  223. setxattr([logPath UTF8String], attrName, &attrValue, sizeof(attrValue), 0, 0);
  224. // init xlog
  225. #if DEBUG
  226. xlogger_SetLevel(kLevelVerbose);
  227. appender_set_console_log(true);
  228. #else
  229. xlogger_SetLevel(kLevelInfo);
  230. appender_set_console_log(false);
  231. #endif
  232. appender_open(kAppednerAsync, [logPath UTF8String], "Test", NULL);
  233. }
  234. + (void)stopLog {
  235. appender_close();
  236. }
  237. - (void)onRecallMessage:(long long)messageUid {
  238. dispatch_async(dispatch_get_main_queue(), ^{
  239. [[NSNotificationCenter defaultCenter] postNotificationName:kRecallMessages object:@(messageUid)];
  240. if ([self.receiveMessageDelegate respondsToSelector:@selector(onRecallMessage:)]) {
  241. [self.receiveMessageDelegate onRecallMessage:messageUid];
  242. }
  243. });
  244. }
  245. - (void)onReceiveMessage:(NSArray<WFCCMessage *> *)messages hasMore:(BOOL)hasMore {
  246. dispatch_async(dispatch_get_main_queue(), ^{
  247. NSMutableArray *messageList = [messages mutableCopy];
  248. for (WFCCMessage *message in messages) {
  249. for (id<ReceiveMessageFilter> filter in self.messageFilterList) {
  250. if ([filter onReceiveMessage:message]) {
  251. [messageList removeObject:message];
  252. break;
  253. }
  254. }
  255. }
  256. [[NSNotificationCenter defaultCenter] postNotificationName:kReceiveMessages object:messages];
  257. [self.receiveMessageDelegate onReceiveMessage:messageList hasMore:hasMore];
  258. });
  259. }
  260. - (void)addReceiveMessageFilter:(id<ReceiveMessageFilter>)filter {
  261. [self.messageFilterList addObject:filter];
  262. }
  263. - (void)removeReceiveMessageFilter:(id<ReceiveMessageFilter>)filter {
  264. [self.messageFilterList removeObject:filter];
  265. }
  266. - (void)onDisconnected {
  267. mars::baseevent::OnDestroy();
  268. }
  269. - (void)setCurrentConnectionStatus:(ConnectionStatus)currentConnectionStatus {
  270. NSLog(@"Connection status changed to (%ld)", (long)currentConnectionStatus);
  271. if (_currentConnectionStatus != currentConnectionStatus) {
  272. _currentConnectionStatus = currentConnectionStatus;
  273. [[NSNotificationCenter defaultCenter] postNotificationName:kConnectionStatusChanged object:@(_currentConnectionStatus)];
  274. if (_connectionStatusDelegate) {
  275. [_connectionStatusDelegate onConnectionStatusChanged:currentConnectionStatus];
  276. }
  277. }
  278. }
  279. - (void)onConnectionStatusChanged:(ConnectionStatus)status {
  280. if (!_logined || kConnectionStatusRejected == status) {
  281. dispatch_async(dispatch_get_global_queue(0, DISPATCH_QUEUE_PRIORITY_DEFAULT), ^{
  282. [self disconnect:YES];
  283. });
  284. return;
  285. }
  286. if((int)status == (int)mars::stn::kConnectionStatusServerDown) {
  287. status = kConnectionStatusUnconnected;
  288. }
  289. dispatch_async(dispatch_get_main_queue(), ^{
  290. self.currentConnectionStatus = status;
  291. if (status == kConnectionStatusConnected) {
  292. if (self.backupDeviceToken.length) {
  293. [self setDeviceToken:self.backupDeviceToken];
  294. }
  295. if (self.backupVoipDeviceToken.length) {
  296. [self setVoipDeviceToken:self.backupVoipDeviceToken];
  297. }
  298. }
  299. });
  300. }
  301. + (WFCCNetworkService *)sharedInstance {
  302. if (sharedSingleton == nil) {
  303. @synchronized (self) {
  304. if (sharedSingleton == nil) {
  305. sharedSingleton = [[WFCCNetworkService alloc] init];
  306. }
  307. }
  308. }
  309. return sharedSingleton;
  310. }
  311. - (instancetype)init {
  312. self = [super init];
  313. if (self) {
  314. _currentConnectionStatus = kConnectionStatusLogout;
  315. _messageFilterList = [[NSMutableArray alloc] init];
  316. [[NSNotificationCenter defaultCenter] addObserver:self
  317. selector:@selector(onAppSuspend)
  318. name:UIApplicationDidEnterBackgroundNotification
  319. object:nil];
  320. [[NSNotificationCenter defaultCenter] addObserver:self
  321. selector:@selector(onAppResume)
  322. name:UIApplicationWillEnterForegroundNotification
  323. object:nil];
  324. [[NSNotificationCenter defaultCenter] addObserver:self
  325. selector:@selector(onAppTerminate)
  326. name:UIApplicationWillTerminateNotification
  327. object:nil];
  328. }
  329. return self;
  330. }
  331. - (void)startBackgroundTask {
  332. if (!_logined) {
  333. return;
  334. }
  335. if (_bgTaskId != UIBackgroundTaskInvalid) {
  336. [[UIApplication sharedApplication] endBackgroundTask:_bgTaskId];
  337. }
  338. _bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
  339. if (_suspendTimer) {
  340. [_suspendTimer invalidate];
  341. _suspendTimer = nil;
  342. }
  343. if(_endBgTaskTimer) {
  344. [_endBgTaskTimer invalidate];
  345. _endBgTaskTimer = nil;
  346. }
  347. if(_forceConnectTimer) {
  348. [_forceConnectTimer invalidate];
  349. _forceConnectTimer = nil;
  350. }
  351. _bgTaskId = UIBackgroundTaskInvalid;
  352. }];
  353. }
  354. - (void)onAppSuspend {
  355. if (!_logined) {
  356. return;
  357. }
  358. [self reportEvent_OnForeground:NO];
  359. self.backgroudRunTime = 0;
  360. [self startBackgroundTask];
  361. [self checkBackGroundTask];
  362. }
  363. - (void)checkBackGroundTask {
  364. if(_suspendTimer) {
  365. [_suspendTimer invalidate];
  366. }
  367. if(_endBgTaskTimer) {
  368. [_endBgTaskTimer invalidate];
  369. _endBgTaskTimer = nil;
  370. }
  371. NSTimeInterval timeInterval = 3;
  372. _suspendTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval
  373. target:self
  374. selector:@selector(suspend)
  375. userInfo:nil
  376. repeats:NO];
  377. }
  378. - (void)suspend {
  379. if(_bgTaskId != UIBackgroundTaskInvalid) {
  380. self.backgroudRunTime += 3;
  381. if (mars::stn::GetTaskCount() > 0 && self.backgroudRunTime < 60) {
  382. [self checkBackGroundTask];
  383. } else {
  384. mars::stn::Reset();
  385. _endBgTaskTimer = [NSTimer scheduledTimerWithTimeInterval:1
  386. target:self
  387. selector:@selector(endBgTask)
  388. userInfo:nil
  389. repeats:NO];
  390. }
  391. }
  392. }
  393. - (void)endBgTask {
  394. if(_bgTaskId != UIBackgroundTaskInvalid) {
  395. [[UIApplication sharedApplication] endBackgroundTask:_bgTaskId];
  396. _bgTaskId = UIBackgroundTaskInvalid;
  397. }
  398. if (_suspendTimer) {
  399. [_suspendTimer invalidate];
  400. _suspendTimer = nil;
  401. }
  402. if(_endBgTaskTimer) {
  403. [_endBgTaskTimer invalidate];
  404. _endBgTaskTimer = nil;
  405. }
  406. if (_forceConnectTimer) {
  407. [_forceConnectTimer invalidate];
  408. _forceConnectTimer = nil;
  409. }
  410. self.backgroudRunTime = 0;
  411. }
  412. - (void)onAppResume {
  413. if (!_logined) {
  414. return;
  415. }
  416. [self reportEvent_OnForeground:YES];
  417. mars::stn::MakesureLonglinkConnected();
  418. [self endBgTask];
  419. }
  420. - (void)onAppTerminate {
  421. }
  422. - (void)dealloc {
  423. }
  424. - (void) createMars {
  425. mars::app::SetCallback(mars::app::AppCallBack::Instance());
  426. mars::stn::setConnectionStatusCallback(new CSCB(self));
  427. mars::stn::setReceiveMessageCallback(new RPCB(self));
  428. mars::stn::setRefreshUserInfoCallback(new GUCB(self));
  429. mars::stn::setRefreshGroupInfoCallback(new GGCB(self));
  430. mars::stn::setRefreshChannelInfoCallback(new GCHCB(self));
  431. mars::stn::setRefreshFriendListCallback(new GFLCB(self));
  432. mars::stn::setRefreshFriendRequestCallback(new GFRCB(self));
  433. mars::stn::setRefreshSettingCallback(new GSCB(self));
  434. mars::baseevent::OnCreate();
  435. }
  436. - (void)connect:(NSString *)host port:(int)port {
  437. mars::stn::Connect([host UTF8String], port);
  438. dispatch_async(dispatch_get_main_queue(), ^{
  439. if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
  440. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  441. if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
  442. [self onAppSuspend];
  443. }
  444. });
  445. }
  446. });
  447. }
  448. - (void)forceConnectTimeOut {
  449. if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
  450. [self onAppSuspend];
  451. }
  452. }
  453. - (void)forceConnect:(NSUInteger)second {
  454. dispatch_async(dispatch_get_main_queue(), ^{
  455. if (_logined &&[UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
  456. [self onAppResume];
  457. [self startBackgroundTask];
  458. _forceConnectTimer = [NSTimer scheduledTimerWithTimeInterval:second
  459. target:self
  460. selector:@selector(forceConnectTimeOut)
  461. userInfo:nil
  462. repeats:NO];
  463. }
  464. });
  465. }
  466. - (void)cancelForceConnect {
  467. dispatch_async(dispatch_get_main_queue(), ^{
  468. if (_forceConnectTimer) {
  469. [_forceConnectTimer invalidate];
  470. _forceConnectTimer = nil;
  471. }
  472. if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
  473. [self onAppSuspend];
  474. }
  475. });
  476. }
  477. - (long long)serverDeltaTime {
  478. return mars::stn::getServerDeltaTime();
  479. }
  480. - (NSString *)getClientId {
  481. return [UIDevice currentDevice].identifierForVendor.UUIDString;
  482. }
  483. - (void)connect:(NSString *)userId token:(NSString *)token {
  484. _logined = YES;
  485. mars::app::AppCallBack::Instance()->SetAccountUserName([userId UTF8String]);
  486. [self createMars];
  487. self.userId = userId;
  488. self.passwd = token;
  489. mars::stn::setAuthInfo([userId cStringUsingEncoding:NSUTF8StringEncoding], [token cStringUsingEncoding:NSUTF8StringEncoding]);
  490. self.currentConnectionStatus = kConnectionStatusConnecting;
  491. [[WFCCNetworkStatus sharedInstance] Start:[WFCCNetworkService sharedInstance]];
  492. [self connect:self.serverHost port:self.serverPort];
  493. }
  494. - (void)disconnect:(BOOL)clearSession {
  495. _logined = NO;
  496. self.userId = nil;
  497. self.currentConnectionStatus = kConnectionStatusLogout;
  498. [[WFCCNetworkStatus sharedInstance] Stop];
  499. if (mars::stn::getConnectionStatus() != mars::stn::kConnectionStatusConnected && mars::stn::getConnectionStatus() != mars::stn::kConnectionStatusReceiving) {
  500. [self destroyMars];
  501. } else {
  502. mars::stn::Disconnect(clearSession ? 8 : 0);
  503. }
  504. }
  505. - (void)setServerAddress:(NSString *)host port:(uint)port {
  506. self.serverHost = host;
  507. self.serverPort = port;
  508. }
  509. - (void)destroyMars {
  510. [[WFCCNetworkStatus sharedInstance] Stop];
  511. mars::baseevent::OnDestroy();
  512. }
  513. // event reporting
  514. - (void)reportEvent_OnForeground:(BOOL)isForeground {
  515. mars::baseevent::OnForeground(isForeground);
  516. }
  517. - (void)setDeviceToken:(NSString *)token {
  518. if (token.length == 0) {
  519. return;
  520. }
  521. if (!self.isLogined || self.currentConnectionStatus != kConnectionStatusConnected) {
  522. self.backupDeviceToken = token;
  523. return;
  524. }
  525. NSString *appName =
  526. [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"];
  527. mars::stn::setDeviceToken([appName UTF8String], [token UTF8String], mars::app::AppCallBack::Instance()->GetPushType());
  528. }
  529. - (void)setVoipDeviceToken:(NSString *)token {
  530. if (token.length == 0) {
  531. return;
  532. }
  533. if (!self.isLogined || self.currentConnectionStatus != kConnectionStatusConnected) {
  534. self.backupVoipDeviceToken = token;
  535. return;
  536. }
  537. NSString *appName =
  538. [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"];
  539. mars::stn::setDeviceToken([appName UTF8String], [token UTF8String], 2);
  540. }
  541. - (void)onGroupInfoUpdated:(NSArray<WFCCGroupInfo *> *)updatedGroupInfo {
  542. dispatch_async(dispatch_get_main_queue(), ^{
  543. for (WFCCGroupInfo *groupInfo in updatedGroupInfo) {
  544. [[NSNotificationCenter defaultCenter] postNotificationName:kGroupInfoUpdated object:groupInfo.target userInfo:@{@"groupInfo":groupInfo}];
  545. }
  546. });
  547. }
  548. - (void)onChannelInfoUpdated:(NSArray<WFCCChannelInfo *> *)updatedChannelInfo {
  549. dispatch_async(dispatch_get_main_queue(), ^{
  550. for (WFCCChannelInfo *channelInfo in updatedChannelInfo) {
  551. [[NSNotificationCenter defaultCenter] postNotificationName:kChannelInfoUpdated object:channelInfo.channelId userInfo:@{@"channelInfo":channelInfo}];
  552. }
  553. });
  554. }
  555. - (void)onUserInfoUpdated:(NSArray<WFCCUserInfo *> *)updatedUserInfo {
  556. dispatch_async(dispatch_get_main_queue(), ^{
  557. for (WFCCUserInfo *userInfo in updatedUserInfo) {
  558. [[NSNotificationCenter defaultCenter] postNotificationName:kUserInfoUpdated object:userInfo.userId userInfo:@{@"userInfo":userInfo}];
  559. }
  560. });
  561. }
  562. - (void)onFriendListUpdated {
  563. dispatch_async(dispatch_get_main_queue(), ^{
  564. [[NSNotificationCenter defaultCenter] postNotificationName:kFriendListUpdated object:nil];
  565. });
  566. }
  567. - (void)onFriendRequestUpdated {
  568. dispatch_async(dispatch_get_main_queue(), ^{
  569. [[NSNotificationCenter defaultCenter] postNotificationName:kFriendRequestUpdated object:nil];
  570. });
  571. }
  572. - (void)onSettingUpdated {
  573. dispatch_async(dispatch_get_main_queue(), ^{
  574. [[NSNotificationCenter defaultCenter] postNotificationName:kSettingUpdated object:nil];
  575. });
  576. }
  577. #pragma mark WFCCNetworkStatusDelegate
  578. -(void) ReachabilityChange:(UInt32)uiFlags {
  579. if ((uiFlags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) {
  580. mars::baseevent::OnNetworkChange();
  581. }
  582. }
  583. @end