¿Qué hacer cuando la solicitud se envía al servidor y mientras se espera la respuesta, se perdió la conectividad a Internet?

14

Estoy enviando una gran cantidad de datos al servidor. Ahora, mientras envié los datos y espero la respuesta del servidor, de repente mi dispositivo Android pierde la conexión a Internet.
Entonces, lo que solía hacer es mostrar un diálogo de alerta de pérdida de conexión, pero en el lado del servidor los datos ya se procesaron y se actualizaron en algún lugar, por ejemplo, en cualquier URL. Pero mi teléfono Android no lo sabe, ya que nunca recibió respuesta. Como resolverlo.
Si podría hacerse en el lado del servidor o en el propio Android ¿Cómo?
¿Cómo sabría el servidor que el teléfono Android no va a escuchar la respuesta?
Puede ser la perspectiva de optimización de la comunicación cliente-servidor.

mayank_droid
fuente
¿De cuántos datos estamos hablando? Gigabytes?
Daniel Hollinrake
No hay entre 7 y 8 MB, pero el tiempo de respuesta del servidor es demasiado largo y la velocidad de carga del teléfono es de alrededor de 128 KB / S. No estoy hablando del tamaño de los datos sino del problema de conexión.
mayank_droid

Respuestas:

15

Este es un problema bastante común con las transacciones asincrónicas, y se divide en varias partes.

  1. ¿Cómo saben ambas partes que la solicitud de transacción se ha recibido con éxito?
  2. ¿Cómo reenvía una solicitud de transacción que el cliente cree que no se recibió correctamente?
  3. ¿Cómo detecta el servidor las solicitudes repetidas del cliente cuando el servidor recibió con éxito la primera solicitud?
  4. ¿Cómo sabe el cliente de dónde obtener los resultados de la transacción?

Lo mejor de HTTP es que es bastante fácil resolver todos estos problemas.

Imagine una estructura de URL como esta:

POST http://my.server.com/application/engine/queue 
OBTENGA   http://my.server.com/application/engine/results?jobid=43425

Usar la publicación HTTP para enviar una solicitud al servidor, usar una identificación de solicitud de cliente única, y hacer que el servidor responda con la ID del trabajo. Desde la perspectiva del cliente, si esta respuesta no ocurre, entonces la solicitud debe ser reenviada. Desde la perspectiva de los servidores, los ID de solicitud del cliente deben almacenarse en caché durante unos minutos, en caso de que el cliente envíe solicitudes duplicadas. Las solicitudes duplicadas se manejan simplemente devolviendo la misma ID de trabajo al cliente.

El cliente obtiene los resultados de la solicitud de la URL de resultados. Esta llamada se puede repetir tantas veces como sea necesario para obtener los resultados. Si se llama antes de que los resultados estén disponibles, entonces la respuesta podría ser una respuesta SIN CONTENIDO para que el cliente sepa que el servidor reconoce la identificación del trabajo pero aún no tiene el contenido. Si la identificación del trabajo no se reconoce, NOT-FOUND es la respuesta adecuada.

El resultado final es que el cliente siempre puede realizar una acción sensata cuando la red se pierde y se recupera, y del mismo modo, el servidor siempre puede procesar las solicitudes del cliente con sensatez

Michael Shaw
fuente
3
Eso, o simplemente haciendo una solicitud corta pidiendo una ID de transacción, luego varias solicitudes agregando datos a la transacción (puede dividir la transferencia en fragmentos más pequeños aquí, para obtener confirmaciones parciales), luego una solicitud final de "confirmación". Luego puede tener diferentes tiempos de espera para transacciones completamente vacías (el cliente probablemente no recibió ID), transacciones parcialmente cargadas y resultados (si el cliente no recibió los resultados, puede volver a intentar la solicitud de "confirmación").
Simon Richter
Eso gestionaría la situación en la que se perdió la conexión durante la transmisión de la solicitud. La pregunta que se hace es hablar sobre la conexión perdida después de que se enviaron los datos, pero antes de procesar la solicitud se ha completado.
Michael Shaw
1
Eso también se maneja. La transacción "commit" es pequeña y utiliza el ID de la transacción, por lo que puede volver a emitirse a bajo costo sin retransmitir los datos, y el servidor puede comenzar a procesar o devolver el resultado de la invocación anterior. Esto es muy similar a lo que estás sugiriendo; la diferencia es que tengo una solicitud por separado para crear la ID del trabajo, por lo que tengo un punto de sincronización adicional, para que el cliente pueda saber si el trabajo ya existe sin retransmitir la solicitud completa.
Simon Richter
Sí, eso tiene sentido.
Michael Shaw
De esta manera, si una transacción contiene datos parciales en el servidor, sé que existe un cliente que conoce esta ID e intenta completar la transacción, por lo que puedo mantener el estado parcial y ofrecer reanudar la transmisión a la mitad, minimizando los requisitos de ancho de banda y eliminando el necesita comparar el contenido de la solicitud para encontrar duplicados.
Simon Richter
4

Esto cae bajo los fundamentos de la comunicación de protocolo. El cliente de Android ha solicitado una transacción y el servidor debe realizar la transacción. Si la transacción depende del acuse de recibo del cliente de Android, entonces llame a la comunicación ACK / NAK.

ACK (acuse de recibo) y NAK (acuse de recibo negativo) se utilizan para informar al otro lado el resultado de una solicitud.

Lo que se está planteando es un tipo de protocolo de enlace de intercambio entre el cliente y el servidor, y puede llevarse a cabo con un ACK de cambio básica / NAK.

Aquí hay un ejemplo de Android cargando un archivo con reconocimiento bidireccional.

Android -> upload files -> Server
Android <- ACK #id <- Server
Android -> ACK #id -> Server

En el ejemplo anterior, agregué un #ididentificador único para la transacción. El servidor debe recibir los archivos, crear un registro de transacciones y enviarlo como respuesta a Android. Android debería seguir con un reconocimiento de esa transacción (o alternativamente un NAK para un rechazo).

Aquí hay un ejemplo de una desconexión de Android durante el apretón de manos.

Android -> upload files -> Server
Android <- ACK #id <- Server
/** no ACK response **/

En el ejemplo anterior, el Servidor ha aceptado los archivos cargados y envió una #idrespuesta ACK a Android, pero Android nunca responde con un ACK. El dispositivo Android no ha podido completar el apretón de manos. Depende de usted decidir cómo debe manejar esto el servidor. Destruya la transacción, conserve la transacción y espere a que el dispositivo Android regrese más tarde o complete la transacción de todos modos.

El servidor puede suponer que ya que el dispositivo no respondió con ACK. Que el dispositivo Android no actualizó su estado interno para indicar que la carga se realizó correctamente. Descartaría la transacción y permitiría que el dispositivo la repita en el futuro.

Reactgular
fuente