Pregunta

conecto de forma asíncrona con el servidor cada 5 segundos. La URL es la misma, pero POST-cuerpo se cambia cada vez. Ahora creo NSURL, NSURLRequest y NSURLConnection desde cero cada vez.

Creo que sería más eficaz para establecer la conexión de una vez y sólo tiene que utilizar más que uno. Soy un novato y no está seguro de si eso es posible. No hay ninguna NSURLConnection mutable, pero se puede necesitar para crear NSURLConnection como:

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

y cambiar NSMutableURLRequest de datos posteriores a enviar otra solicitud al servidor. En qué dirección es la correcta?

¿Fue útil?

Solución

Asumo lo que le preocupa es la sobrecarga de crear la conexión HTTP. NSURLConnection es lo suficientemente inteligente como para manejar esto para usted a través de HTTP / 1.1 y la reutilización de las conexiones existentes. No utilizar la canalización última vez que revisé, pero para su propósito, la reutilización de conexiones debería ser suficiente. Os animo a poner un sniffer de red en esto y asegurarse de que está funcionando como se desea.

El coste de la creación de los objetos en sí es trivial en el orden de una vez por 5s y no debe tratar de optimizar que (aunque, por supuesto, debe volver a utilizar el NSURL). Es la apertura de una conexión con el servidor que es caro, sobre todo en el iPhone.

Si usted encuentra que realmente necesita la canalización, que lamentablemente tendrá que rodar su propia. He oído que CFHTTPStream puede hacerlo, pero no veo una gran cantidad de evidencia de ello. CocoaAsyncSocket es la mejor opción para el acceso de bajo nivel a los enchufes sin tener que escribir código de bajo nivel.

Dado que la latencia de la red celular puede ser muy malo, es posible que su conexión tardará más de 5 años en completarse. No asegurarse de que una conexión se realiza antes de iniciar la siguiente, o tendrá que empezar a hacer cada vez más abiertas conexiones.

Otros consejos

Sólo para aclarar las cosas, NSURLConnection reutilizará zócalos existentes, pero sólo por un período de tiempo relativamente pequeña (12 segundos). Si envía una solicitud, volver una respuesta, y enviar una solicitud posterior dentro de los 12 segundos que segunda solicitud se salió en el mismo socket. De lo contrario el zócalo se cerrará por el cliente. Un error se ha presentado con Apple para aumentar este temporizador o para que sea configurable.

@ Rob Napier @Eric Nelson Como usted ha mencionado: "NSURLConnection es lo suficientemente inteligente como para manejar esto para usted a través de HTTP / 1.1 y la reutilización de las conexiones existentes". Sin embargo, no puedo encontrar tal descripción en el documento de ninguna de Apple al respecto.

Para hacer cosa clara, escribo algo de código para probarlo:

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

Y entonces, comienzo Wireshark para capturar paquetes en el servidor (192.168.1.xxx), usando "(tcp.flags.syn == 1) || (tcp.flags == == 0x0010 && tcp.seq 1 && tcp.ack == 1)" para filtrar tcp de 3 vías sacudida de la mano. Por desgracia, no puedo ver el temblor de la mano de 3 vías para cada llamado de "sendOneRequest". Lo que significa, la NSURLConnection parece no reutilizar las conexiones existentes. ¿Puede alguien señalar lo que está mal en mi código y cómo enviar múltiples peticiones a través de una conexión de socket por NSURLConnection?

También probé manera sincrónica a enviar solicitud:

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

}

Y el resultado es el mismo.

======= ACTUALIZACIÓN ============================

Por último, he encontrado la razón por la que mi prueba es diferente de decir Rob y Eric. En resumen, Rob y Eric son correctos. Y NSURLConnection utiliza “keep-alive” por defecto para el uso de HTTP / 1.1 y reutiliza conexión de socket existente, pero sólo por un período de tiempo relativamente pequeña.

Sin embargo, NSURLConnection tiene algunos problemas para “fragmentada transferencia codificante” (es decir. Sin contenido de longitud).

En mi prueba, el servidor envían una respuesta sin datos de contenido de larga duración y respuesta, y está fragmentada respuesta y NSURLConnection cerrará la conexión, por tanto, de 3 vías apretón de manos se produce para cada puesto http.

he cambiado de código del servidor, defina la longitud de la respuesta no es 0, y el comportamiento es correcto.

hacer un método que devuelve una petición y hacer

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top