iOS开发:为什么我总是在第一次尝试时发生"连接失败",但下一次成功?

Bea*_*red 17 iphone ruby-on-rails asihttprequest ipad ios

我在我的iOS应用程序中使用ASIHTTPRequest lib来向我的Rails 3 Web应用程序发出RESTful请求.我第一次尝试向我的网络应用程序发出POST请求时看到一个奇怪且有些一致的错误,但是POST请求在第二次尝试时工作正常.确切的错误是......

Error Domain=ASIHTTPRequestErrorDomain Code=1 "A connection failure occurred" UserInfo=0xb513740 {NSUnderlyingError=0xb5135a0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1005.)", NSLocalizedDescription=A connection failure occurred}
Run Code Online (Sandbox Code Playgroud)

这是我的ASIHTTPRequest代码,用于发出POST请求...

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myrails3app.heroku.com/tournaments/%d/register.json", tid]];
    __block ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
    [request setRequestMethod:@"POST"];
    [request addPostValue:username forKey:@"username"];

    [request setCompletionBlock:^
    {
        NSData *responseData = [request responseData];     
        NSLog(@"Success!");
    }];

    // Set the code to be called when the request fails
    [request setFailedBlock:^
     {
         NSError *error = [request error];
         NSLog(@"Error: %@", [error localizedDescription]);
     }];

    // Start the request
    [request startAsynchronous];
Run Code Online (Sandbox Code Playgroud)

值得一提的是,当它出错时,它出错的速度非常快!另外,对于它的价值,我正在发出POST请求的我的Rail 3应用程序是在Heroku上托管的.你的意见?

非常感谢你的智慧!

Pie*_*ult 30

这个问题我很难弄明白为什么.问题在于ASIHTTPRequest本身(iOS),而不是rails代码.

总而言之,问题特定于ASIHTTPRequest发送的每个请求使用持久连接.

虽然这对GET请求很有用,但大多数服务器实现都不允许将持久连接与POST请求一起使用.

我没有时间在服务器端深入调查它,但我认为问题在于应该发送的100-Continue标头(并且不是)与附加了主体的请求(因此PUT/POST).如果您想深入了解我正在谈论的内容,请阅读规格表:http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html

因此,ASIHTTPRequest使用的持久连接等待发送100响应,永远不会发送.所以最终会超时.

修复方法是将persistentConnection设置为NO,其中包含以下发布请求:

ASIHTTPRequest *req                     = [ASIHTTPRequest requestWithURL:url];
req.shouldAttemptPersistentConnection   = NO;
Run Code Online (Sandbox Code Playgroud)

  • 从v1.8.1开始,ASIHTTPRequest默认情况下不会对带有正文的请求使用持久连接(例如POST/PUT) - 请参阅http://allseeing-i.com/ASIHTTPRequest/Changelog-我向所有被抓住的人道歉这个问题. (5认同)