IOS 网络编程 + 后台保持连接
Posted zj510
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOS 网络编程 + 后台保持连接相关的知识,希望对你有一定的参考价值。
昨天在os x上写了个网络通信的小程序http://blog.csdn.net/zj510/article/details/8934312,今天在iphone也试了一下。
使用了Cocoa中的NSStream.代码相当的简单。
- (void)Work_Thread:(NSURL *)url
NSString* strHost = [url host];
int port = [[url port] integerValue];
[NSStream getStreamsToHostNamed:strHost port: port inputStream:&readStream outputStream:&writeStream];
[readStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
[readStream setDelegate:self];
[readStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[readStream open];
NSLog(@"VOIP stream, %x", readStream);
[writeStream open];
[writeStream write:"abcd" maxLength:4];
NSInputStream* iStream;
[NSStream getStreamsToHostNamed:strHost port:port inputStream:&iStream outputStream:nil];
[iStream setDelegate: self];
[iStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[iStream open];
NSLog(@"normal stream: %x", iStream);
[[NSRunLoop currentRunLoop] run];
这是个线程函数,里面创建了2个socket连接,并且关联到当前线程的run-loop。
为了接收NSStream的事件,需要实现NSStreamDelegate,如
@interface KMasterViewController : UITableViewController <NSStreamDelegate>
- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
NSLog(@" >> NSStreamDelegate in Thread %@", [NSThread currentThread]);
switch (eventCode)
case NSStreamEventHasBytesAvailable:
uint8_t buf[100] = 0;
int numBytesRead = [(NSInputStream *)stream read:buf maxLength:100];
NSString* str = [NSString stringWithFormat:@"recv: %s", buf];
UILocalNotification* n = [[[UILocalNotification alloc] init] autorelease];
[n setAlertBody:[NSString stringWithFormat:@"notify: %x", stream]];
[[UIApplication sharedApplication] presentLocalNotificationNow:n];
break;
case NSStreamEventErrorOccurred:
break;
case NSStreamEventEndEncountered:
break;
default:
break;
收到数据后,显示一条notification。
就这么简单,使用http://blog.csdn.net/zj510/article/details/8934312里面的server,打开iphone程序,就可以收数据了。
但是这里有一个问题,iphone程序切到后台后,socket连接会断掉,ios的设计就是这样,好在apple公司也没有那么绝,还是有一些东西可以在后台运行的,比如:
1. 音乐
2. gps
3. voip
这里我们可以将NSStream指定voip的属性,从而可以避免程序切到后台的时候socket连接中断。
步骤如下:
1. 在info.plist文件中,增加voip选项,如
2. 设置NSStream的属性,如
[readStream setProperty:NSStreamNetworkServiceTypeVoIP forKey:NSStreamNetworkServiceType];
这样,当程序切到后台的时候,这个socket连接还会被保持。上面的示例代码里面有2个连接,一个采用了voip属性,另外一个没有。
这样的话,当这个程序切到后台后,只有voip属性的那个socket还有效,另外一个将会失效。我测试了一下,确实是这样的。
另外,iphone都是通过wifi或者gprs上网的,那么当socket连接空闲一段时间后,这个连接有可能被路由器关闭,为了保持连接,我们需要不停发送心跳包。
由于iphone上的程序切到后台后,程序会被挂起,那么也就无法定时发送心跳包,所以这个问题只能由服务端来解决。普通的办法就是服务器每隔一定时间给每个客户端发送一个心跳包,以维持这个连接。每当客户端接收到心跳包的时候,客户端会被IOS唤醒,获得一小段CPU时间,然后再次进入挂起状态。
相关测试代码:http://download.csdn.net/detail/zj510/5390813
以上是关于IOS 网络编程 + 后台保持连接的主要内容,如果未能解决你的问题,请参考以下文章
iOS socket保持后台连接 ios9.0 xcode8.0
如何在后台保持 iphone ios websocket 连接处于活动状态?