iOS 后台保持長連接


工程中使用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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM