Primero: Gracias por la respuesta.
Segundo: el script para pruebas lo he basado en las funciones y especificaciones que he encontrado a través del foro
El clean_session está a False, porque de hecho, luego conecto ese mismo cliente con un script que accede directamente al puerto 1883, desde un equipo sin proxy delante, y según el protocolo MQTT, y al realizar la conexión me recupera instantánemante todos los mensajes pendientes que han llegado en el periodo de desconexión sin ningún problema.
Función que uso para la creación de la sesión (python 3.8). El socket de conexión ya lo he abierto previamente ( no sé si hay alguna mejor forma de meter código en el mensaje)
Funcion para crear la sesion
def create_session (client_id, user_name, password, clean_session = True):
#Parte de una conexión de red abierta
dbg (“MQTT CONNECT - mqtt_client=%s, mqtt_user=%s)” % (client_id, user_name))
# build login parameters do login
params = {
'clientId' : client_id,
'userName' : user_name,
'password' : password,
'cleanSession' : clean_session
}
# send request
conn.request ("POST", "/login", json.dumps (params), headers = {"Connection":" keep-alive"})
result = conn.getresponse()
body = result.read ()
dbg ("INFO: login request result: %s" % body)
if result.status != 200:
# close connection
conn.close ()
return (False, "LOGIN ERROR: status=%d, reason=%s :: %s" % (result.status, result.reason, body), None)
# Login ok
login_data = json.loads (body)
dbg ("MYQTT CONNECT: login request: status=%d, reason=%s :: %s (token: %s)" % (result.status, result.reason, login_data, login_data['tokenId']))
# return data from login
session = {'login_data' : login_data, 'conn' : conn, 'client_id' : client_id, 'user_name' : user_name}
return (True, "Login ok", session)
Llamada que hago a ella desde mi código:
(status, info, session) = create_session (mqtt_client, mqtt_user, mqtt_password, clean_session = False)
Esto es un ejemplo de lo que muestra la función de conexión en su dbg:
INFO: login request result: b’{“clientId”:“xxx0000”,“validUntil”:1574932504,“stamp”:1574759704,“cleanSession”:false,“tokenId”:“ce7213a5-521f-442e-8145-bafc9adfbea7”}’
Función que uso para llamar al pull:
def pull(session):
“”"
Pide los mensajes pendientes desde la última petición
Parametros:
session – [Object] created by create_session
“”"
# get login session and connection
(conn, login_data, params, headers) = __prepare_headers (session)
# send PULL
dbg ("PULL :: (clientId=%s, userName=%s).." % (session['client_id'], session['user_name']))
conn.request ("POST", "/pull", json.dumps (params), headers)
dbg ("INFO: enviada solicitud de mensajes pendientes para el cliente")
result = conn.getresponse()
body = result.read ().decode('utf-8')
if result.status != 200:
return (False, "Error obteniendo mensajes del bróker: status=%d, reason=%s :: %s" % (result.status, result.reason, body))
dbg("Mensaje devuelto: status=%d, reason=%s :: %s" % (result.status, result.reason, body))
return (True, body)
Llamada a recoger mensajes con pull:
(status_pull,info_pull) = pull(session)
if status_pull:
if len(info_pull)>2: #Quiere decir que hay algún mensaje
trataRespuesta(info_pull)
else:
print(“No hay mensajes pendientes”)
La funcion trataRespuesta simplemente trata la cadena recibida, separando las distintas unidades delimitadas por {} y tratándolas con json.
Como comentaba, los mensajes que han entrado desde el anterior pull se reciben, pero lo que veo, y me produce problemas:
- si han sido enviado con QoS 1 no quedan confirmados
- no recibo los pendientes de entregar a ese cliente existentes en el broker antes del primer pull realizado para la sesión (parece que es funcionamiento normal del pull según la descripción de la API -mensajes recibidos desde el anterior pull-, pero me supone un problema, ya que no sé cómo recibir esos mensajes a través de la API.