La conexión TCP SIM5320 MQTT se cierra inesperadamente después de un tiempo

7

He estado trabajando en un protocolo MQTT usando el SIM5320. Estoy familiarizado con la documentación del comando AT y tengo una implementación funcional con un Arduino.

Primero, abro un socket de red con AT + NETOPEN, luego abro una conexión TCP con AT + CIPOPEN = 0, "TCP", "dirección IP", puerto. Luego transmito datos para el protocolo MQTT usando AT + CIPSEND, que se ejecuta con éxito. Si envío datos al módulo SIM a través de MQTT, también se reciben y se detecta el mensaje.

Con MQTT, hay un intervalo Keep-Alive que especifica cuánto tiempo el servidor mantendrá una conexión abierta entre comunicaciones, básicamente cuánto tiempo puede estar inactivo el cliente antes de ser desconectado por la fuerza del servidor. Sin embargo, he establecido este valor en el máximo de 18 horas, que es mucho más largo que las desconexiones de ~ 15 minutos.

Mi problema surge después de ~ 15 minutos, cuando intento enviar un comando al servidor, y no recibo respuesta. La SIM no ha emitido un "+ IPCLOSE: 0,4", que generalmente ocurre cuando el servidor desconecta por la fuerza al cliente o cualquier otro tipo de indicador.

Además, todavía puedo enviar datos y parece que la conexión CIP todavía está abierta, como lo indica "AT + CIPOPEN?". Cuando intento cerrar la conexión con "AT + CIPCLOSE = 0", recibo "+ CIPCLOSE: 0,4" y "ERROR". No se menciona lo que significa "+ CIPCLOSE: 0,4" en la documentación, sin embargo, no parece cerrar la conexión, ya que no se puede abrir ni utilizar.

Realmente me encantaría saber qué está sucediendo en estos 15 minutos, entre establecer una conexión y enviar datos, hasta intentar enviarlos nuevamente. No hay ninguna alerta o indicación de que algo salga mal, así que estoy seriamente confundido.

Inicialmente hice esta pregunta sobre el intercambio de pila de Ingeniería Eléctrica, pero me aconsejaron que también la hiciera aquí.

He adjuntado el código que escribí aquí para cualquiera que quiera echar un vistazo, y no hay ninguna biblioteca que necesite para ejecutarlo.

Boris Deletic
fuente
2
Observando el intervalo MQTT Keep Alive Explicado , parecería que la causa más probable es que la conexión de transporte se está cayendo en algún punto dentro de la pila de comunicaciones. El envío de datos debe mantener activa la comunicación MQTT y el intermediario debe enviar pings nuevamente si no está enviando nada más. Entonces, ¿podría el módem irse a dormir si no hay actividad? Una pregunta sería si podría enviar un mensaje de ping cada 10 minutos cuando no hay otro tráfico y cómo sucede.
Richard Chambers el
1
Si envío una solicitud de ping antes de que se corte la conexión, entonces la conexión permanece activa. Sin embargo, enviar solicitudes de ping cada 10 minutos es más problemático que enviarlas cada 18 horas. Si es posible, me gustaría enviar solicitudes solo cada hora más o menos.
Boris Deletic el
2
¿Qué idioma y bibliotecas MQTT está utilizando para su cliente? Actualice su pregunta publicada con esta información.
Richard Chambers el
1
El OP está utilizando un módulo 3G que envía paquetes TCP / IP basados ​​en comandos AT enviados al módulo a través de un enlace UART. No hay Linux involucrado aquí en absoluto. El OP básicamente está escribiendo su propio cliente MQTT.
hardillb
1
@hardillb ok, eso aclara un poco las cosas. Entonces, si el OP está escribiendo su propio cliente MQTT desde cero, parecería que el trabajo debería seguir la especificación MQTT que incluye los pings MQTT Keep Alive necesarios.
Richard Chambers el

Respuestas:

7

El tiempo de espera predeterminado de TCP / IP es de 15 minutos, debe enviar algo dentro de este intervalo para mantener viva la conexión TCP subyacente, incluso si es solo un par de sincronización / confirmación.

El keepalive de MQTT tiene que ver con cuándo activar los mensajes Last Will y Testement.

hardillb
fuente
1
El keepalive de MQTT tiene que ver con cuándo decidir cerrar lo que puede ser una conexión inactiva o una conexión en vivo a un agente inactivo (cliente o corredor). Esto a su vez desencadena la Última Voluntad y el Testamento. Keepalive no es activar Last Will and Testament, sino más bien decidir si una conexión está inactiva, cerrarla y, como parte del cierre de la conexión, activar Last Will and Testament.
Richard Chambers el
1
¿Podría proporcionar más detalles sobre el tiempo de espera de TCP / IP al que se refiere? Supongo que está hablando del tiempo de espera de transmisión no reconocido que no parece aplicarse a la pregunta publicada, pero no estoy seguro. Y de acuerdo con man7.org/linux/man-pages/man7/tcp.7.html hay tcp_keepalive_time()un valor predeterminado de 7200 segundos después del cual se envían los mensajes vivos si la SO_KEEPALIVEopción de socket está configurada. De lo contrario, la conexión se termina.
Richard Chambers el
1
Esta parece ser la causa del problema, ¿podría agregar una cita y sugerir un posible método para aumentar este intervalo para el SIM5320?
Boris Deletic
Estamos viendo algo muy similar con nuestra configuración MQTT: TCP parece desconectarse pero el cliente / intermediario MQTT no lo sabe. Cuando publicamos después de ~ 30 minutos de inactividad, no se recibe un PUBACK del agente, pero en lo que respecta al agente tampoco se ha producido una desconexión.
Steve Magness