sgcMQ en cinco minutos

Este paquete incluye siete clientes de mensajería nativos. MQTT es el camino más corto para tener algo funcionando, así que eso es lo que hace esta página: conectarse a un broker, suscribirse a un topic, publicar un mensaje y verlo volver. AMQP, Kafka y STOMP siguen la misma estructura de dos componentes.

MQTT 3.1.1 y 5.0, AMQP 0.9.1 y 1.0, Kafka, STOMP
Sin biblioteca externa y sin DLL
Edición Standard y superiores

Dos componentes, no uno

Esta es la parte en la que se atascan muchos. El componente de protocolo habla MQTT; un componente cliente aparte es el dueño del socket. Los conectas con una sola asignación.

El componente de protocolo

TsgcWSPClient_MQTT en la página SGC MQ de la paleta. Incluye Connect, Subscribe, Publish, UnSubscribe y trece eventos MQTT.

El componente de transporte

TsgcWebSocketClient para MQTT sobre WebSockets, o TsgcTCPClient para MQTT normal sobre TCP. Define Host y Port en este.

La línea que los une

MQTT.Client := WSClient;. Después abres la conexión definiendo WSClient.Active := True, no llamando a un método del protocolo.

Plataformas

sgcWebSocket_Protocol_MQTT_Client.pas no tiene guarda de plataforma, solo una importación condicional de Windows, y el componente se registra con ComponentPlatforms(0). Compila en todos los destinos.

Requisitos y ediciones

La columna de edición es el define que controla cada protocolo, con la línea en la que se encuentra en Source/sgcVer.inc.

Qué Valor
IDE Delphi 7 hasta RAD Studio 13, y C++Builder 2007 hasta 13.
Cláusula uses sgcWebSocket_Protocols para TsgcWSPClient_MQTT, sgcWebSocket para el cliente, sgcWebSocket_Classes para TsgcWSConnection y sgcWebSocket_Types para TmqttQoS.
Edición de MQTT SGC_MQTT se define en la línea 717, dentro del bloque {$IFDEF SGC_EDT_STD} que va de la línea 675 a la 724. Es decir, Standard y superiores. Los bloques son acumulativos, así que Professional, Enterprise y All-Access también lo incluyen.
Los demás protocolos Todos en el mismo bloque Standard: SGC_STOMP en la línea 716, SGC_AMQP en la 718, SGC_AMQP1 en la 719, SGC_KAFKA en la 720 y SGC_WAMP en la 715. Ninguno es una característica Enterprise.
Edición, paquete independiente El producto sgcMQ define SGC_PACK_MQ en la línea 855, y su propio bloque de las líneas 959 a 966 activa los mismos cinco defines de protocolo.
Plataformas No hay guarda de plataforma a nivel de unit en la unit del cliente MQTT. El único condicional de su cláusula uses es {$IFDEF MSWINDOWS}Windows, {$ENDIF}.

¿Quieres un broker con el que probar sin instalar uno? La demo de MQTT incluida apunta a un broker de pruebas público en www.esegece.com, puerto 15675 para MQTT sobre WebSockets.

Instala y localiza la página de la paleta

sgcMQ se distribuye dentro del instalador de sgcWebSockets y también como paquete propio. La instalación es la misma en ambos casos.

1. Descomprime

Descomprime la descarga en una carpeta, llamada {$DIR} más abajo.

2. Ruta de biblioteca

Tools, Options, Library. Añade {$DIR}\source y la carpeta lib de tu IDE, por ejemplo {$DIR}\libD13\$(Platform).

3. Compila los paquetes

Abre el grupo de paquetes de tu versión de IDE en {$DIR}\Packages\. Compila primero el .dpk de runtime y después instala el de tiempo de diseño, el dcl.

4. Comprueba la paleta

Aparece una página llamada SGC MQ, con los clientes de protocolo que habilita tu edición. En una compilación Standard y superiores, TsgcWSPClient_MQTT está ahí.

5. Abre la demo

Abre {$DIR}\Demos\02.WebSocket_Protocols\08.MQTT_Client. De ahí procede el código de más abajo, y ya apunta a un broker de pruebas en vivo.

Conectar, suscribirse, publicar

Conecta el protocolo a un cliente, abre la conexión, suscríbete a un topic y publica en él. El mensaje vuelve en OnMQTTPublish.

uClientMQTT.pas
uses
  Classes, SysUtils,
  // sgc
  sgcWebSocket, sgcWebSocket_Classes, sgcWebSocket_Protocols,
  sgcWebSocket_Types, sgcWebSocket_Protocol_MQTT_Client,
  sgcWebSocket_Protocol_MQTT_Message;

procedure TfrmClientPROTOCOL.FormCreate(Sender: TObject);
begin
  WSClient := TsgcWebSocketClient.Create(Self);
  WSClient.Host := 'www.esegece.com';
  WSClient.Port := 15675;
  WSClient.TLS := False;

  // ... attach the client to the MQTT protocol
  MQTT.Client := WSClient;

  // ... and THIS is what opens the connection.
  // There is no Connect call on the protocol component.
  WSClient.Active := True;
end;

Para MQTT normal sobre TCP en lugar de sobre WebSockets, crea en su lugar un TsgcTCPClient de sgcTCP_Client_WS y apunta MQTT.Client a ese. Nada más cambia, y esa es la razón por la que los dos componentes son independientes.

uClientMQTT.pas
procedure TfrmClientPROTOCOL.btnSubscribeClick(Sender: TObject);
begin
  MQTT.Subscribe('sgc/quickstart');
end;

procedure TfrmClientPROTOCOL.btnPublishClick(Sender: TObject);
begin
  // topic, payload, QoS, retain
  MQTT.Publish('sgc/quickstart', 'hello from Delphi',
    mtqsAtLeastOnce, False);
end;

procedure TfrmClientPROTOCOL.btnUnsubscribeClick(Sender: TObject);
begin
  MQTT.UnSubscribe('sgc/quickstart');
end;

Publish devuelve un Word, el identificador del paquete, y no espera. PublishAndWait devuelve un Boolean y bloquea hasta que el broker confirma, con un timeout que por defecto es de diez segundos. TmqttQoS procede de sgcWebSocket_Types.

uClientMQTT.pas
procedure TfrmClientPROTOCOL.MQTTMQTTConnect(Connection: TsgcWSConnection;
  const Session: Boolean; const ReasonCode: Integer;
  const ReasonName: String;
  const ConnectProperties: TsgcWSMQTTCONNACKProperties);
begin
  memoLog.Lines.Add('#connected: ' + ReasonName);
end;

procedure TfrmClientPROTOCOL.MQTTMQTTSubscribe(Connection: TsgcWSConnection;
  aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS;
  SubscribeProperties: TsgcWSMQTTSUBACKProperties);
begin
  memoLog.Lines.Add('#subscribed: ' + IntToStr(aPacketIdentifier));
end;

procedure TfrmClientPROTOCOL.MQTTMQTTPublish(Connection: TsgcWSConnection;
  aTopic, aText: string;
  PublishProperties: TsgcWSMQTTPUBLISHProperties);
begin
  memoLog.Lines.Add(aTopic + ': ' + aText);
end;

Estos son los tres que importan primero. Existen nueve más para el flujo de confirmaciones, la desconexión y la autenticación de MQTT 5.0. Deja que el IDE genere los manejadores, porque las listas de parámetros son largas y los objetos de propiedades cambian según el evento.

Las tres pestañas proceden de la demo incluida Demos\02.WebSocket_Protocols\08.MQTT_Client\uClientMQTT.pas, con los controles del formulario sustituidos por literales. El objeto MQTT está colocado en el formulario de ese proyecto; crearlo por código funciona igual.

Demuestra el viaje de ida y vuelta

Dos eventos te dicen que el broker te aceptó y que el topic está activo.

OnMQTTConnect

El broker aceptó la sesión. ReasonCode y ReasonName te dicen por qué cuando no lo hizo, que es mucho más útil que un socket caído.

OnMQTTSubscribe

La suscripción se concedió. aCodes, un TsgcWSSUBACKS, lleva la respuesta del broker por cada topic, así que una suscripción rechazada es visible y no silenciosa.

OnMQTTPublish

Llegó un mensaje. Publica en el topic al que acabas de suscribirte y vuelve directamente, lo que demuestra todo el camino con un clic.

Los eventos de confirmación

En QoS 1 y 2 la entrega se confirma más tarde, en OnMQTTPubAck, OnMQTTPubRec, OnMQTTPubRel y OnMQTTPubComp. Si necesitas una llamada bloqueante, usa PublishAndWait.

Lo que suele fallar la primera vez

Seis problemas explican casi todas las primeras conexiones fallidas.

No pasa nada al llamar a Subscribe

La conexión todavía no está abierta. El componente de protocolo no abre el socket; lo hace el cliente. Define WSClient.Active := True y espera a OnMQTTConnect antes de suscribirte.

Access violation en la primera llamada

Nunca se asignó MQTT.Client. Esa línea es la que enlaza el protocolo con un transporte, y sin ella el protocolo no tiene dónde escribir.

Puerto equivocado para el transporte equivocado

MQTT sobre WebSockets y MQTT sobre TCP normal usan puertos distintos en la mayoría de los brokers. 1883 y 8883 son los puertos TCP habituales, mientras que el endpoint WebSocket está en otro sitio completamente distinto. La demo incluida usa 15675 para WebSockets.

Estás buscando OnMQTTMessage

Ese evento no existe. Los mensajes entrantes del broker llegan en OnMQTTPublish para texto, y en OnMQTTPublishEx cuando quieres la carga en bruto y el objeto de mensaje completo.

QoS 1 y 2 parece que no hicieron nada

Se confirman de forma asíncrona. Publish devuelve el identificador del paquete de inmediato; la confirmación llega después en OnMQTTPubAck, OnMQTTPubRec, OnMQTTPubRel u OnMQTTPubComp. Usa PublishAndWait cuando quieras una llamada bloqueante.

El broker rechaza la conexión

La mayoría de los brokers quieren un identificador de cliente y credenciales. Defínelos en Authentication, y usa OnMQTTBeforeConnect cuando necesites calcular el identificador de cliente en el momento de conectar.

Más allá del primer topic

La misma estructura de dos componentes sirve para todos los demás protocolos del paquete.

Propiedades de MQTT 5.0

Define MQTTVersion y los objetos de propiedades de petición y respuesta pasan a estar disponibles. Las propiedades de usuario, los identificadores de suscripción, los alias de topic y los códigos de motivo quedan expuestos.

Referencia de MQTT

AMQP, las dos versiones

Dos clientes separados, el 0.9.1 para exchanges y colas al estilo RabbitMQ, y el 1.0 para el protocolo de red más reciente. Ambos se acoplan a un cliente igual que MQTT.

Referencia de AMQP 0.9.1 y referencia de AMQP 1.0

Kafka y STOMP

Un cliente nativo del protocolo de red de Kafka, y STOMP 1.0 a 1.2 con variantes específicas de broker para RabbitMQ y ActiveMQ.

STOMP para RabbitMQ y STOMP para ActiveMQ

Habla con un broker en la nube

AWS IoT y Azure IoT hablan MQTT, y la biblioteca incluye componentes dedicados que se encargan por ti de su firma y autenticación.

Referencia de AWS IoT y referencia de Azure IoT

Referencia, demos y documentación

Las páginas de referencia documentan cada propiedad y evento. Los proyectos de demo se incluyen dentro de la descarga, en Demos\02.WebSocket_Protocols.

Referencia, cliente MQTT Todos los métodos, propiedades y eventos de TsgcWSPClient_MQTT.
Referencia, AMQP 0.9.1 Exchanges, colas, bindings y consumidores.
Referencia, AMQP 1.0 Enlaces, sesiones y el modelo de mensajes de la 1.0.
Página del componente TsgcWSPClient_MQTT El cliente MQTT al completo, con los otros seis clientes de protocolo enlazados desde ella.
Visión general de protocolos Cómo se acoplan los componentes de subprotocolo a un cliente o a un servidor.
Ayuda en línea La referencia generada, siempre al día con la versión actual.

Lecturas relacionadas: publicar y esperar la confirmación, exchanges y colas de AMQP y el cliente de Kafka. Cada producto tiene su propio inicio rápido, listado en la página de primeros pasos.

Preguntas sobre el inicio rápido de sgcMQ

Porque el protocolo y el transporte son asuntos distintos, y eso es lo que permite que el mismo cliente MQTT funcione sobre TCP normal o sobre WebSockets sin cambiar tu código. TsgcWSPClient_MQTT codifica y decodifica los paquetes MQTT. TsgcWebSocketClient o TsgcTCPClient es el dueño del socket, el host, el puerto y los ajustes TLS. Una asignación los une: MQTT.Client := WSClient;.
Define Active := True en el componente cliente, no en el protocolo. La demo incluida hace exactamente eso. También hay un método Connect en el protocolo, pero la demo no lo usa, y definir Active es el camino que siguen todos los ejemplos.
SGC_MQTT se define en la línea 717 de sgcVer.inc, dentro del bloque SGC_EDT_STD que va de la línea 675 a la 724. Es la edición Standard, el nivel de pago más bajo, y los bloques son acumulativos, así que todas las ediciones superiores también lo tienen. STOMP en la línea 716, AMQP en la 718, AMQP 1.0 en la 719 y Kafka en la 720 están todos en el mismo bloque. Ninguno de los protocolos de mensajería es una característica Enterprise.
OnMQTTPublish, cuya firma es procedure(Connection: TsgcWSConnection; aTopic, aText: String; PublishProperties: TsgcWSMQTTPUBLISHProperties). No existe un evento llamado OnMQTTMessage. Cuando necesites los bytes en bruto o el objeto de mensaje completo en lugar de una cadena, gestiona OnMQTTPublishEx.
Publish devuelve un Word, el identificador del paquete. La entrega se confirma de forma asíncrona: en QoS 1 en OnMQTTPubAck, en QoS 2 mediante OnMQTTPubRec, OnMQTTPubRel y OnMQTTPubComp. Si quieres una llamada que bloquee hasta que el broker confirme, usa PublishAndWait, que devuelve un Boolean y acepta un timeout que por defecto es de diez segundos.
El tercer parámetro de Publish es un TmqttQoS, declarado en sgcWebSocket_Types.pas con los miembros mtqsAtMostOnce, mtqsAtLeastOnce, mtqsExactlyOnce y mtqsReserved. Por defecto vale mtqsAtMostOnce. Subscribe acepta el mismo tipo como segundo parámetro.
Sí. sgcWebSocket_Protocol_MQTT_Client.pas no lleva guarda de plataforma a nivel de unit, el único condicional de su cláusula uses es la importación de Windows, y el componente de la paleta se registra con ComponentPlatforms(0), así que el IDE no restringe sus plataformas de destino.
Sí. Define MQTTVersion en el componente de protocolo. Entonces entran en juego los objetos de propiedades de la 5.0: ConnectProperties a la ida, y el parámetro de propiedades de cada evento a la vuelta, por ejemplo TsgcWSMQTTCONNACKProperties en OnMQTTConnect y TsgcWSMQTTPUBLISHProperties en OnMQTTPublish.
La mejor opción: All-AccessTodos los productos de eSeGeCe, con Premium Support incluido, desde €1,059 al año.
Ver precios de All-Access

¿Listo para poner un broker detrás de tu aplicación?

Descarga la versión de prueba y ejecuta la demo de MQTT contra el broker de pruebas público.