当NSStream失去连接时如何重新连接?

时间:2013-05-20 08:27:25

标签: objective-c cocoa-touch sockets nsstream

我正在构建一个监控用户位置的应用程序,并通过套接字将其发送到我们的服务器。 在应用程序启动时,应用程序连接到我们服务器上的套接字,我们是否能够将数据发送到服务器。

但是当用户从小区更改为wifi时,连接会丢失。我想弄清楚如何简单地重新连接(自动),但我无法弄清楚如何。有人能帮助我吗?

我现在使用的代码(LocationRecorder.m):

//
//  LocationRecorder.m
//

#import "LocationRecorder.h"
#import <Cordova/CDV.h>
#import <coreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>

@implementation LocationRecorder

@synthesize locationManager;

NSInputStream *inputStream;
NSOutputStream *outputStream;

- (void)startUpdates
{
    // this only runs once when the app starts up
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;

    [locationManager startUpdatingLocation];
    [locationManager startUpdatingHeading];

    // connect to the socket
    [self initNetworkCommunication];

    // set a timer for every 5 seconds
    [NSTimer scheduledTimerWithTimeInterval:5
                                     target:self
                                   selector:@selector(timerInterval:)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)timerInterval:(NSTimer *) timer
{
    CLLocation *location    = [locationManager location];

    // process location data
    [self processLocationData:location];
}

- (void)processLocationData:(CLLocation *)location
{
    // format all the data to prepare it for sending it to the server

    NSString *response  = [NSString stringWithFormat:stringFormat,
                           utctime,
                           utcdate,
                           lat,
                           lng,
                           alt,
                           speed,
                           heading,
                           imei,
                           numsat,
                           battery,
                           cellno];

    //NSLog(@"%@", @"tx");

    NSData *data = [[NSData alloc] initWithData:[response dataUsingEncoding:NSASCIIStringEncoding]];

    // check for connection
    if ([outputStream streamStatus] != NSStreamStatusOpen) {
        NSLog(@"%@", @"reconnecting...");
        [outputStream open];
    }
    [outputStream write:[data bytes] maxLength:[data length]];
}

- (void)initNetworkCommunication
{
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"***.***.***.***", 9000, &readStream, &writeStream);

    outputStream = (NSOutputStream *)writeStream;
    // we don't initialize the inputStream since we don't need one (the server does not (yet) talk back)

    [outputStream setDelegate:self];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream open];
}

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent
{
    switch (streamEvent)
    {
        case NSStreamEventNone:
            // can not connect to host, no event fired
            break;

        case NSStreamEventOpenCompleted:
            // connected!
            NSLog(@"%@", @"connected to socket");
            break;

        case NSStreamEventErrorOccurred:
            // Connection problem
            NSLog(@"%@", @"connection lost");
            [theStream open]; //this does not work :-(
            break;

        case NSStreamEventEndEncountered:
            // connection closed
            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            [theStream release];
            theStream = nil;
            break;

        default:
            // unknown or untracked event
            break;
    }
}

@end

1 个答案:

答案 0 :(得分:0)

致Martin R的简单解决方案。

我向NSStreamEventErrorOccurred添加了[outputStream close],在我将数据发送到processLocationData中的套接字之前,我添加了以下代码:

// check for connection
if ([outputStream streamStatus] != NSStreamStatusOpen) {
    NSLog(@"reconnecting...", nil);
    [self initNetworkCommunication];
}