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秒に1回程度の些細なものであり、それを最適化しようとしないでください(もちろん、NSURLを再利用する必要があります)。特にiPhoneで高価なサーバーへの接続を開くことです。

本当にパイプラインが必要だとわかった場合は、残念ながら自分でパイプラインを作成する必要があります。CFHTTPStreamでそれができると聞きましたが、その証拠はあまりありません。CocoaAsyncSocketは、低レベルのコードを記述せずにソケットに低レベルでアクセスするための最善の策です。

セルネットワークの遅延は非常に悪い場合があるため、接続が完了するまでに5秒以上かかる可能性があります。次の接続を開始する前に、1つの接続が完了していることを確認してください。そうしないと、ますます多くのオープン接続が開始されます。

于 2009-05-20T14:04:28.913 に答える
6

明確にするために、NSURLConnectionは既存のソケットを再利用しますが、それは比較的短い時間枠(12秒)のみです。リクエストを送信し、レスポンスを返し、12秒以内に後続のリクエストを送信すると、2番目のリクエストが同じソケットで送信されます。それ以外の場合、ソケットはクライアントによって閉じられます。このタイマーを増やすか、設定可能にするために、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)"tcp3ウェイハンドシェイクをフィルタリングします。残念ながら、「sendOneRequest」を呼び出すたびに3ウェイハンドシェイクが発生することがあります。つまり、NSURLConnectionは既存の接続を再利用していないようです。私のコードの何が問題になっているのか、NSURLConnectionによる1つのソケット接続を介して複数のリクエストを送信する方法を誰かが指摘できますか?

リクエストを送信する同期方法も試しました:

-(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];

}

そして結果は同じです。

======= UPDATE ============================

最後に、私のテストがロブやエリックの言うことと異なる理由を見つけました。要するに、ロブとエリックは正しいです。また、NSURLConnectionは、HTTP / 1.1を使用するためのデフォルトとして「keep-alive」を使用し、既存のソケット接続を再利用しますが、比較的短い時間枠でのみ使用されます。

ただし、NSURLConnectionには、「チャンク転送コーディング」(つまり、content-lengthなし)に関していくつかの問題があります。

私のテストでは、サーバー側がコンテンツの長さと応答データなしで応答を送信し、それがチャンク化された応答であり、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 に答える