# iOS应用中通过设置VOIP模式实现休眠状态下socket的长连接

VOIP程序需要稳定的网络去连接和它相关的服务，这样它才能接到来电和其他相关的数据。系统允许VOIP程序被挂断并提供组件去监听它们的sockets，而不是在任意时候都处于唤醒状态。设置VOIP应用程序步骤如下：

A、 添加UIBackgroundModes中的VOIP键值

B、 为VOIP设置一个应用程序socket

1、NSInputStream 和NSOutputStream

NSStreamNetworkServiceType

NSStreamNetworkServiceTypeVoIP.

2、NSURLRequest

method of your NSMutableURLRequest object to set the network service
type of the request. The service type should be set to
NSURLNetworkServiceTypeVoIP.

For Core Foundation streams, use the CFReadStreamSetProperty or
CFWriteStreamSetProperty function to add the kCFStreamNetwork-
ServiceType property to the stream. The value for this property should be
set to kCFStreamNetworkServiceTypeVoIP.
（注意：当设置socket的时候,你需要在你的主信号通道中设置合适的service type key。当设置声道时，不需要设置这个key）

C、 在移出后台之前，调用setKeepAliveTimeout:handler:方法去建立一个定期执行的handler，你的应用程序可以运行这个handler来保持服务的连接

1、在创建socket并且成功连接上远程服务器的delegate中执行下述代码
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)connectedPort{
[socket performBlock:^{
[socket enableBackgroundingOnSocket];
}];
}

2、在ApplicationDidEnterBackground方法中调用setKeepAliveTimeOut以保持长连接
BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];
if (backgroundAccepted)
{
NSLog(@"VOIP backgrounding accepted");
}


1、XMPP中长连接问答

2、GCDAsyncSocket实现后台长连接的VOIP问答

3、后台运行（内容比较杂，但还是很有参考价值）

4、有一篇国内的关于VOIP以及后台程序的博文（内容还是比较杂－－还是英文的，估计只能由博主自己看懂，仅做参考）
http://blog.csdn.net/gnicky/article/details/7452418

5、iOS socket编程基础

6、一篇StackOverflow.com中的问答，其中对iOS中对VOIP的解释比较详细
If you want to let your VOIP application run in background , except those base settings in plist file, you need a TCP socket who's property is set to VOIP, than the iOS system will take care this socket for you, when your application enter background , every thing was 'sleep' except that tcp socket. and if VOIP server send some data thought that TCP socket, your application will be awake up for 10 secs. during this time, you can post a local notification.

Only Tcp socket can be set as VOIP Socket. But from i know , mostly VOIP application are based on UDP socket. if you do not want to separate the control socket from the data socket. you should create another tcp socket which is focus on 'awake' your application , and from my personal experience , it's very hard to keep this 'awake' signal and the real sip control signal synchronize, the application always miss the sip invite request.

So,the best way is separating the sip control single from the UDP data socket , make it as a tcp socket , this is the best solution , but never use tcp socket to transfer voice data.

Another dirty way: keep the application awake all the time. As i said , each TCP single the application received thought that 'VOIP' tcp socket , will keep application awake for 10 seconds, so at the end of this duration(after 9 secs) , you can send a response to the server to ask for another signal , when the next signal arrived, the application will be awake again,after 9 secs , send response again. keep doing this, your application will awake forever.

7.CocoaAsyncSocket

07-28 5997

08-19 2.1万

06-17 3571

11-22 1261

03-03 287

06-15 13

#### Xamarin使用C#开发IOS程序-socket与突破3分钟后台运行限制

2015年12月01日 2.05MB 下载