7

我每 5 秒与服务器异步连接一次。URL 是相同的,但 POST-body 每次都会更改。现在我每次都从头开始创建 NSURL、NSURLRequest 和 NSURLConnection。

我认为设置一次连接并进一步使用它会更有效。我是新手,不确定这是否可能。没有可变的 NSURLConnection,但可能需要创建 NSURLConnection,例如:

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

并更改 NSMutableURLRequest POST-data 以向服务器发送另一个请求。哪种方式是正确的?

4

4 回答 4

10

我假设您关心的是创建 HTTP 连接的开销。NSURLConnection 足够聪明,可以使用 HTTP/1.1 和重用现有连接为您处理这个问题。我上次检查时它没有使用流水线,但为了您的目的,连接重用应该就足够了。我确实鼓励您为此安装网络嗅探器,并确保它按您希望的方式工作。

创建对象本身的成本大约是每 5 秒一次,您不应该尝试优化它(当然您应该重用 NSURL)。打开与服务器的连接很昂贵,尤其是在 iPhone 上。

如果你发现你真的需要流水线,很遗憾你将不得不自己动手。我听说 CFHTTPStream 可以做到这一点,但我没有看到很多证据。CocoaAsyncSocket 是您无需编写低级代码即可对套接字进行低级访问的最佳选择。

由于蜂窝网络上的延迟可能非常糟糕,因此您的连接可能需要超过 5 秒才能完成。请确保在开始下一个连接之前完成一个连接,否则您将开始建立越来越多的开放连接。

于 2009-05-20T14:04:28.913 回答
6

只是为了澄清一下,NSURLConnection 将重用现有的套接字,但仅在相对较短的时间范围内(12 秒)。如果你发送一个请求,得到一个响应,并在 12 秒内发送一个后续请求,第二个请求将在同一个套接字上发出。否则客户端将关闭套接字。已向 Apple 提交了一个错误以增加此计时器或使其可配置。

于 2012-04-30T17:12:21.860 回答
3

@Rob Napier @Eric Nelson 正如您所提到的:“NSURLConnection 足够聪明,可以使用 HTTP/1.1 和重用现有连接为您处理这个问题”。但是,我在任何 Apple 的文档中都找不到这样的描述。

为了清楚起见,我编写了一些代码来测试它:

- (IBAction)onClickSend:(id)sender {
    [self sendOneRequest];
}

-(void)sendOneRequest {

    NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
    [request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
    [request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
}

然后,我使用 "(tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp 启动 Wireshark 以捕获服务器 (192.168.1.xxx) 上的包.ack==1)" 过滤 tcp 3 向握手。不幸的是,我可以看到每次调用“sendOneRequest”的 3 次握手。这意味着, NSURLConnection 似乎没有重用现有的连接。有人可以指出我的代码有什么问题以及如何通过 NSURLConnection 通过一个套接字连接发送多个请求吗?

我还尝试了同步方式发送请求:

-(void)sendOneRequest {
    NSURL *url = [NSURL URLWithString:@"http://192.168.1.100:1234"];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    [request setHTTPMethod:@"POST"];
    [request addValue:[Base64 encodeFromString:kValueVersion] forHTTPHeaderField:kKeyVersion];
    [request addValue:[Base64 encodeFromString:kValueDataTypeCmd] forHTTPHeaderField:kKeyDataType];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyCmdName];
    [request addValue:[Base64 encodeFromString:@"Test"] forHTTPHeaderField:kKeyDeviceName];
    [request addValue:[Base64 encodeFromString:@"xxdafadfadfa"] forHTTPHeaderField:kKeyDTLCookies];

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    sleep(1);

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

    sleep(1);

    [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];

}

结果是一样的。

=======更新=============================

最后,我找到了我的测试与 Rob 和 Eric 所说的不同的原因。简而言之,Rob 和 Eric 是正确的。并且 NSURLConnection 使用“keep-alive”作为使用 HTTP/1.1 的默认值,并重用现有的套接字连接,但仅适用于相对较短的时间范围。

然而,NSURLConnection 对于“分块传输编码”(即没有内容长度)存在一些问题。

在我的测试中,服务器端发送一个没有内容长度和响应数据的响应,它是分块响应,NSURLConnection 将关闭连接,因此每个 http 帖子都会发生 3 次握手。

我更改了我的服务器代码,将响应长度设置为 0,并且行为正确。

于 2013-05-06T07:47:59.507 回答
0

制作一个返回请求的方法并执行

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:[self requestMethod] delegate:self];

?

于 2009-05-20T11:21:21.503 回答