Conexão SIM5320 MQTT TCP fechando inesperadamente após o tempo

7

Eu tenho trabalhado em um protocolo MQTT usando o SIM5320. Eu estou familiarizado com a documentação do comando AT e tenho uma implementação funcional com um Arduino.

Primeiramente, abro um soquete de rede com AT + NETOPEN e, em seguida, abro uma conexão TCP com AT + CIPOPEN = 0, "TCP", "endereço IP", porta. Em seguida, transmito dados para o protocolo MQTT usando AT + CIPSEND, que é executado com sucesso. Se eu enviar dados para o módulo SIM através do MQTT, eles também serão recebidos e a mensagem será detectada.

Com o MQTT, há um intervalo Keep-Alive que especifica por quanto tempo o servidor manterá uma conexão aberta entre a comunicação, basicamente por quanto tempo o cliente pode ficar ocioso antes de ser desconectado à força do servidor. No entanto, eu configurei esse valor para o máximo de 18 horas, que é muito mais longo que as desconexões de ~ 15 minutos.

Meu problema surge após ~ 15 minutos, quando tento enviar um comando para o servidor e nenhuma resposta é dada. O SIM não emitiu um "+ IPCLOSE: 0,4", que geralmente ocorre quando o servidor desconecta à força o cliente ou qualquer outro tipo de indicador.

Além disso, ainda posso enviar dados e parece que a conexão CIP ainda está aberta, conforme indicado por "AT + CIPOPEN?". Quando tento fechar a conexão com "AT + CIPCLOSE = 0", recebo "+ CIPCLOSE: 0,4" e "ERRO". Não há menção do que "+ CIPCLOSE: 0,4" significa na documentação, no entanto, parece não fechar a conexão, pois não pode ser aberta ou usada.

Eu realmente adoraria saber o que está acontecendo nesses 15 minutos, entre estabelecer uma conexão e enviar dados, para tentar enviar dados novamente. Não há alerta ou indicação de que algo esteja errado, então estou seriamente confuso.

Inicialmente, fiz essa pergunta na troca de pilhas de engenharia elétrica, mas fui aconselhada a fazer aqui também.

Anexei o código que escrevi aqui para quem gostaria de dar uma olhada e não há bibliotecas necessárias para executá-lo.

Boris Deletic
fonte
2
Olhando para o MQTT Keep Alive Interval Explained , parece que a causa mais provável é que a conexão de transporte esteja sendo descartada em algum momento da pilha de comunicações. O envio de dados deve manter a comunicação MQTT ativada e o broker deve enviar pings de volta para baixo, caso não esteja enviando mais nada. Então, o modem poderia estar entrando no modo de suspensão se não houver atividade? Uma pergunta seria se você poderia enviar uma mensagem de ping a cada 10 minutos quando não houver outro tráfego e como isso acontece.
Richard Chambers
11
Se eu enviar uma solicitação de ping antes da conexão cair, ela permanecerá ativa. No entanto, enviar solicitações de ping a cada 10 minutos é mais problemático do que enviá-las a cada 18 horas. Se possível, gostaria de enviar solicitações apenas a cada hora.
Boris Deletic
2
Qual idioma e bibliotecas MQTT você está usando para seu cliente? Atualize sua pergunta postada com essas informações.
Richard Chambers
11
O OP está usando um módulo 3G que envia pacotes TCP / IP com base nos comandos AT enviados ao módulo por um link UART. Não há Linux envolvido aqui. O OP está basicamente escrevendo seu próprio cliente MQTT.
hardillb
11
@hardillb ok que esclarece um pouco as coisas. Portanto, se o OP estiver gravando seu próprio cliente MQTT do zero, parece que o trabalho deve seguir a especificação MQTT, que inclui os pings necessários do MQTT Keep Alive.
Richard Chambers

Respostas:

7

O tempo limite padrão do TCP / IP é de 15 minutos. Você deve enviar algo dentro desse intervalo para manter a conexão TCP subjacente ativa, mesmo que seja apenas um par de sincronização / confirmação.

O keepalive do MQTT refere-se a quando acionar as mensagens Last Will e Testement.

hardillb
fonte
11
O keepalive do MQTT refere-se a quando decidir fechar o que pode ser uma conexão morta ou uma conexão ativa com um agente morto (cliente ou broker). Por sua vez, isso desencadeia a Última Vontade e o Testamento. Keepalive não é para acionar Last Will and Testament, mas sim decidir se uma conexão está morta, fechá-la e como parte do fechamento da conexão para acionar Last Will and Testament.
Richard Chambers
11
Você poderia fornecer mais detalhes sobre o tempo limite do TCP / IP a que se refere? Suponho que você esteja falando sobre o tempo limite de transmissão não reconhecido que parece não se aplicar à pergunta postada, mas não tenho certeza. E, de acordo com man7.org/linux/man-pages/man7/tcp.7.html, existe tcp_keepalive_time()um valor padrão de 7200 segundos, após o qual keep alives são enviados se a SO_KEEPALIVEopção socket estiver configurada. Caso contrário, a conexão será encerrada.
Richard Chambers
11
Isso parece ser a causa do problema. Você poderia adicionar uma citação e sugerir um possível método para aumentar esse intervalo para o SIM5320?
Boris Deletic #
Estamos vendo algo muito semelhante à nossa configuração do MQTT - o TCP parece desconectar, mas o cliente / broker do MQTT não tem conhecimento. Quando publicamos após aproximadamente 30 minutos de inatividade, um PUBACK não é recebido do broker, mas, no que diz respeito ao broker, uma desconexão também não ocorreu.
Steve Magness