从 iPhone 上的 Web 服务器请求数据会造成过多的延迟

Posted

技术标签:

【中文标题】从 iPhone 上的 Web 服务器请求数据会造成过多的延迟【英文标题】:Requesting data from Web Server on iPhone creates too much of a delay 【发布时间】:2011-01-12 10:14:13 【问题描述】:

在我的 iPhone 应用程序中,我需要访问网络服务器才能登录我的系统。客户端要求数据库仅在服务器上。所以我在 ASP.NET 和 mysql 数据库中创建了一个管理面板,用于存储登录信息。

现在,当我在代码中使用下面给出的方法从服务器获取数据时,响应需要花费太多时间(即超过一分钟)。

如果我之前从服务器获取了特定数据,那么当我下次尝试获取它时会快速获取该值。但是对于新数据,它又需要大量时间,或者更确切地说是超时。

有时请求甚至超时。

我应该怎么做才能减少延迟并加快整个登录过程?

有没有更好的方法来做到这一点?

关于以下代码的信息:

firstname.text 是我的用户名。

lastname.text 是我的密码。

label.text 是我用来存储从服务器获取的密码的临时标签。

allUsers 是存储从服务器获得的响应的数组。

我也使用 JSON 来解析网络服务器和 iPhone 之间的数据。

我使用 plist 来存储我的网址。 Plist 名称是 url.plist

代码如下:

    SBJSON *json = [SBJSON new];
    json.humanReadable = YES;
    NSString *service = @"/getUserInfo";
    //NSString *requestString = [NSString stringWithFormat:@"\"method\":\"%@\"",  service];
    NSString *requestString = [NSString stringWithFormat:@"\"firstname\":\"%@\"",firstName.text,nil];
    NSLog(@"Request String: %@", requestString);

    NSData *requestData = [NSData dataWithBytes: [requestString UTF8String] length: [requestString length]];

    NSString *fileLoc = [[NSBundle mainBundle] pathForResource:@"url" ofType:@"plist" ];
    NSDictionary *fileContents = [[NSDictionary alloc] initWithContentsOfFile:fileLoc];
    NSString *urlLoc = [fileContents objectForKey:@"baseURL"];
    urlLoc = [urlLoc stringByAppendingString:service];
    NSLog(@"URL is %@",urlLoc);
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: 
                                    [NSURL URLWithString: urlLoc]];  

    NSString *postLength = [NSString stringWithFormat:@"%d", [requestData length]];
    [request setHTTPMethod: @"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody: requestData];

    //Data returned by WebService
    NSError *respError = nil; 
    NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: &respError ];

    if (respError) 
        NSString *msg = [NSString stringWithFormat:@"Connection failed! Error - %@ %@",
                         [respError localizedDescription],
                         [[respError userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]];   

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Check your network connection" 
                                                            message:msg delegate:self cancelButtonTitle:@"OK" 
                                                  otherButtonTitles:nil];
        [alertView show];


        NSArray *keys = [NSArray arrayWithObjects:@"firstname", @"lastname", nil];
        NSArray *objects = [NSArray arrayWithObjects:@"failed to", @"refresh data...", nil];
        NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

        allUsers = [[NSArray alloc] initWithObjects:dictionary, nil];
        //[self setUserData:allUsers];
        //[tblView reloadData];

        //[allUsers release];

     
    else
    

        NSString *responseString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];

        NSDictionary *results = [responseString JSONValue];
        // Additional steps as the webservice is adding an additional "d:" so stripping of that
        NSString *extractUsers = [results objectForKey:@"d"];

        // The actual string that Web services returned, so re-scan the same and convert it as object
        NSDictionary *finalResult = [extractUsers JSONValue];
        allUsers = [finalResult objectForKey:@"users"];
        NSLog(@"Data is : %@",allUsers);
        NSLog(@"Final Value is : %@",[[allUsers objectAtIndex:0] valueForKey:@"lastname"]);
        if([allUsers count]>0)
        
            label.text = [[allUsers objectAtIndex:0] valueForKey:@"lastname"];
        
        else 
        
            label.text = @"";
        
        [responseString release];
        [request release];

    




    [inProgressIndicator stopAnimating];
    [fileContents release];

    //Release all the allocated data
    [json release];


【问题讨论】:

正如 Nickolay 所说,问题可能出在服务器端。例如,MySQL 服务器可能配置为按需启动,这意味着您第一次使用该服务时,它必须启动数据库服务器。我首先要确保问题不是服务。为此,您可以确保它也响应带有查找键作为参数的 GET 请求,然后只需将 Web 浏览器指向它。 【参考方案1】:

首先,您应该检查发生在哪一侧的延迟 - 是服务器的延迟(可能是未优化的数据库使用等)、互联网连接问题还是其他问题。 只需跟踪并检查,那一分钟首先执行了哪一行代码。

【讨论】:

我的服务器在我的本地主机上。所以我不认为互联网速度应该有任何问题。那么您能否参考我上面发布的代码并让我知道可能导致此延迟的原因? 我没有看到任何可能导致延迟的东西,所以我认为问题出在服务器端。 我尝试调试代码,我发现这一行造成了延迟: NSData *returnData = [NSURLConnection sendSynchronousRequest: request returnedResponse: nil error: &respError ];有什么问题? 你检查过,服务器产生响应的速度有多快? 既然是localhost,那么如何判断它的快慢呢?

以上是关于从 iPhone 上的 Web 服务器请求数据会造成过多的延迟的主要内容,如果未能解决你的问题,请参考以下文章

如何从iPhone中的WebService获取数据?

从 iPhone 同步服务器上的数据时出现超时问题

将数据从 iPhone 应用程序发送到 Node.js Web 服务器

11.WEB通讯

如何从 iPhone 应用程序将数据写入 Web 服务器?

如何使用来自iPhone应用程序的SOAP请求将图像+ xml上传到Web服务器