標籤:
工程中使用tcp長串連來和服務端進行資料轉送,在IOS平台上,由於蘋果的後台機制,會有以下問題:
當程式退到背景時候,所有線程被掛起,系統會回收所有的socket資源,那麼socket串連就會被關閉,因此無法再進行資料的傳輸:
解決方案:
通過設定以下屬性可以保持socket串連和資料的繼續傳輸
1.需要在Info.plist檔案中添加UIBackgroundModes中的VOIP索引值;
2.設定流屬性
CFReadStreamRef和CFWriteStreamRef通過如下方法設定kCFStreamNetworkServiceType屬性為kCFStreamNetworkServiceTypeVoIP;
CFReadStreamSetProperty(theReadStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(theWriteStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
NSInputStream 和NSOutputStream通過如下方法設定NSStreamNetworkServiceType屬性為NSStreamNetworkServiceTypeVoIP;
[self.stream setProperty: NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
3.這裡有一個問題,就是用戶端是通過心跳來和服務端保持串連,心跳是由定時器觸發的,當我退到後台以後,定時器方法被掛起,那麼通過如下設定來在後台運行定時器
1 - (void)applicationDidEnterBackground:(UIApplication *)application{ 2 3 UIApplication* app = [UIApplication sharedApplication]; 4 __block UIBackgroundTaskIdentifier bgTask; 5 bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 6 dispatch_async(dispatch_get_main_queue(), ^{ 7 if (bgTask != UIBackgroundTaskInvalid) 8 { 9 bgTask = UIBackgroundTaskInvalid;10 }11 });12 }];13 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{14 dispatch_async(dispatch_get_main_queue(), ^{15 if (bgTask != UIBackgroundTaskInvalid)16 {17 bgTask = UIBackgroundTaskInvalid;18 }19 });20 });21 }
iOS 後台保持長串連