IOS 网络编程 + 后台保持连接 - Go语言中文社区

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


 




 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zj510/article/details/8935683
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-06-14 02:17:30
  • 阅读 ( 1105 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢