iOS流在中间剪切长消息

时间:2013-10-31 19:13:19

标签: ios iphone objective-c

我有一点功能可以与我的Nodejs服务器说话:

- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
    NSLog(@"stream event %i", streamEvent);

    switch (streamEvent) {

        case NSStreamEventOpenCompleted:
            NSLog(@"Stream opened");
            break;
        case NSStreamEventHasBytesAvailable:

            if (theStream == inputStream) {
                uint8_t buffer[1024];
                int len;

                while ([inputStream hasBytesAvailable]) {
                    len = [inputStream read:buffer maxLength:sizeof(buffer)];
                    if (len > 0) {


                        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];

                        if (nil != output) {

                            // Parse the message and add it to the right method
                            NSError* error;
                            NSDictionary *JSON =
                            [NSJSONSerialization JSONObjectWithData: [output dataUsingEncoding:NSUTF8StringEncoding]
                                                            options: NSJSONReadingMutableContainers
                                                              error: &error];

                            NSString* type = [JSON objectForKey:@"type"];

                            NSLog(@"SERVER TYPE: %@\n", type);
                            NSLog(@"SERVER SENT: %@\n", output);

                            if([type isEqualToString:@"visitorLoad"]) {
                                NSLog(@"New visitor load: %@", output);
                                [self visitorReceived:output];

                            } else if([type isEqualToString:@"message"]) {
                                NSLog(@"New chat message: %@", output);

                                [self messageReceived:output];

                            } else if([type isEqualToString:@"offlineMessages"]) {
                                //NSLog(@"New offline messages: %@", output);
                                NSLog(@"NEW OFFLINE MESSAGES!!");
                                [self offlineMessagesReceived:output];

                            } else if([type isEqualToString:@"agentMsg"]) {
                                NSLog(@"New AGENT MESSAGE: %@", output);

                                [self agentMessageReceived:output];

                            } else if([type isEqualToString:@"heartbeat"]) {
                                // Take no action
                                NSLog(@"Heartbeat recieved");

                            } else if([type isEqualToString:@"visitorExit"]) {

                                [self visitorHasGoneOffline:output];

                            }
                        }
                    }
                }
            }
            break;


        case NSStreamEventErrorOccurred:

            NSLog(@"Can not connect to the host!");
            isConnected = 0;
            //[self initNetworkCommunication];
            break;

        case NSStreamEventEndEncountered:

            [theStream close];
            [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            //[theStream release];
            NSLog(@"STREAM PAUSED");
            theStream = nil;

            break;
        default:
            NSLog(@"Unknown event");
    }

}

问题是,当我从我的节点服务器发送大量JSON消息时,上面将它分成多个部分,使我无法解析。

这是我打开流的方式:

// Open connection to server
- (void)initNetworkCommunication {
    isConnected = TRUE;
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"server.com", 8080, &readStream, &writeStream);
    inputStream = (__bridge NSInputStream *)readStream;
    outputStream = (__bridge NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

    [inputStream open];
    [outputStream open];

    [self openDB];
    [self createTable];
}

任何可能导致这种情况的想法?我100%确定邮件是从我的servern正确发送的。只有当邮件很大且包含大量数据时才会出现此问题。

2 个答案:

答案 0 :(得分:1)

你有它。试试

    case NSStreamEventHasBytesAvailable:

uint8_t buffer[1024];
int len;
NSMutableData *data = [[NSMutableData alloc] init];
while ([inputStream hasBytesAvailable]) {
   len = [inputStream read:buffer maxLength:sizeof(buffer)];
   if (len > 0) {
       [data appendBytes:buffer length:len];
   }
}


NSError* error;
NSDictionary *JSON =[NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &error];

答案 1 :(得分:0)

我与NSURLConnection有完全相同的问题。大数据似乎被削减了一半,导致JSON转换产生NULL。

也许你应该合并

中的所有数据
case NSStreamEventHasBytesAvailable
   NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
   wholeString  = [wholeString stringByAppendString:output];

然后在

中转换为JSON
    case NSStreamEventEndEncountered
       NSDictionary *JSON =[NSJSONSerialization JSONObjectWithData: [wholeString dataUsingEncoding:NSUTF8StringEncoding]
                                                                options: NSJSONReadingMutableContainers
                                                                  error: &error];
       ...
祝你好运!