¿En qué podemos ayudarte?
MQTT
MQTT es un protocolo de transporte de mensajería de publicación / suscripción de Client Server. Es liviano, abierto, simple y está diseñado para que sea fácil de implementar. Estas características lo hacen ideal para su uso en muchas situaciones, incluidos entornos restringidos como la comunicación en los contextos de Máquina a Máquina (M2M) e Internet de las Cosas (IoT) donde se requiere una pequeña huella de código y / o el ancho de banda de la red es primordial. Cita de la especificación oficial MQTT 3.1.1
El resumen de la especificación MQTT hace un buen trabajo al describir de qué se trata MQTT. Es un protocolo muy ligero y binario, que sobresale cuando se transfieren datos a través del cable en comparación con protocolos como HTTP, ya que solo tiene una sobrecarga de paquetes mínima. Otro aspecto importante es que MQTT es extremadamente fácil de implementar en el lado del cliente. Esto encaja perfectamente para dispositivos restringidos con recursos limitados. En realidad, este fue uno de los objetivos cuando se inventó MQTT en primer lugar.
Historia
MQTT fue inventado por Andy Stanford-Clark (IBM) y Arlen Nipper (Arcom, ahora Cirrus Link) en 1999, cuando su caso de uso era crear un protocolo para la pérdida mínima de la batería y el mínimo ancho de banda que conectaba los oleoductos a través de la conexión satelital. Especificaron los siguientes objetivos, que el futuro protocolo debería tener:
- Simple de implementar
- Proporcionar una calidad de servicio de entrega de datos
- Ligero y ancho de banda eficiente
- Agnóstico de datos
- Sesión continua de conciencia
Estos objetivos siguen siendo el núcleo de MQTT, mientras que el enfoque ha cambiado de los sistemas embebidos propietarios para abrir los casos de uso de Internet de las cosas. Otra cosa que a menudo se confunde acerca de MQTT es el significado apropiado de la abreviatura MQTT. Es una larga historia, la respuesta corta es que MQTT oficialmente ya no tiene un acrónimo, es solo MQTT.
La larga historia es que el acrónimo anterior significaba: MQ Telemetry Transport MQ se refiere a MQ Series, un producto desarrollado por IBM que soporta MQTT y el protocolo fue nombrado después, cuando se inventó en 1999. A menudo, MQTT se denomina incorrectamente como mensaje protocolo de cola, pero esto no es cierto. No hay colas como en las soluciones de colas de mensajes tradicionales. Sin embargo, es posible poner un mensaje en cola en ciertos casos, pero esto se tratará en detalle más adelante. Por lo tanto, después de que IBM haya utilizado internamente MQTT durante bastante tiempo, la versión 3.1 se lanzó sin royalties en 2010. Desde allí, todo el mundo podría implementarla y usarla.
Descripción del protocolo
Así que ahora hemos aprendido mucho acerca de la publicación / suscripción en general, pero ¿qué hay de MQTT en particular? MQTT incorpora todos los aspectos mencionados, dependiendo de lo que quiera lograr con él. MQTT desacopla el espacio del editor y el suscriptor. Así que solo tienen que saber el nombre de host / ip y el puerto del agente para publicar / suscribirse a los mensajes. También se desacopla del tiempo, pero a menudo esto es solo un comportamiento de retroceso, porque el caso de uso es principalmente el mensaje de entrega casi en tiempo real. Por supuesto, el agente puede almacenar mensajes para clientes que no están en línea. (Esto requiere dos condiciones: el cliente se ha conectado una vez y su sesión es persistente y se ha suscrito a un tema con Calidad de servicio superior a 0). MQTT también puede desacoplar la sincronización, porque la mayoría de las bibliotecas de clientes funcionan de forma asíncrona y se basan en devoluciones de llamada o en un modelo similar. Por lo tanto, no bloqueará otras tareas mientras espera un mensaje o publica un mensaje. Pero hay ciertos casos de uso donde la sincronización es deseable y también posible. Por lo tanto, algunas bibliotecas tienen API sincrónicas para esperar un mensaje determinado. Pero normalmente el flujo es asíncrono. Otra cosa que debe mencionarse es que MQTT es especialmente fácil de usar en el lado del cliente. La mayoría de los sistemas pub / sub tienen la mayor lógica en el lado del agente, pero MQTT es realmente la esencia de pub / sub cuando se usa una biblioteca cliente y eso lo convierte en un protocolo liviano para dispositivos pequeños y restringidos.
MQTT utiliza filtrado de mensajes basado en el sujeto. Por lo tanto, cada mensaje contiene un tema, que el agente utiliza para averiguar si un cliente suscrito recibirá el mensaje o no. Para manejar los desafíos de un pub / subsistema en general, MQTT tiene los niveles de calidad de servicio (QoS). Es fácilmente posible especificar que un mensaje se entregue correctamente desde el cliente al intermediario o desde el intermediario a un cliente. Pero todavía existe la posibilidad de que nadie se suscriba al tema en particular. Si esto es un problema, depende del agente cómo manejar dichos casos. Para mitigar la inflexibilidad de los temas, es importante diseñar el árbol de temas con mucho cuidado y dejar espacio para la extensión de los casos de uso en el futuro. Si sigue estas estrategias, MQTT es perfecto para configuraciones de producción. Como hemos visto, MQTT desacopla al editor y al suscriptor, por lo que la conexión de cualquier cliente es siempre con el intermediario. Antes de comenzar a profundizar en los detalles de la conexión, aclaremos lo que queremos decir por cliente y agente.
Patrón de publicación/suscripción
El patrón de publicación / suscripción (pub / sub) es una alternativa al modelo cliente-servidor tradicional, donde un cliente se comunica directamente con un punto final. Sin embargo, Pub / Sub desacopla a un cliente, que está enviando un mensaje en particular (llamado editor) de otro cliente (o más clientes), que está recibiendo el mensaje (llamado suscriptor). Esto significa que el editor y el suscriptor no saben de la existencia del otro. Hay un tercer componente, llamado intermediario, conocido tanto por el editor como por el suscriptor, que filtra todos los mensajes entrantes y los distribuye en consecuencia. Así que vamos a profundizar un poco más en los detalles que acabamos de mencionar. Recuerde que esta sigue siendo la parte básica de pub / sub en general, hablaremos de los detalles de MQTT en solo un minuto.
As already mentioned the main aspect in pub/sub is the decoupling of publisher and receiver, which can be differentiated in more dimensions:
- Space decoupling: Publisher and subscriber do not need to know each other (by ip address and port for example)
- Time decoupling: Publisher and subscriber do not need to run at the same time.Synchronization decoupling: Operations on both components are not halted during publish or receiving
In summary publish/subscribe decouples publisher and receiver of a message, through filtering of the messages it is possible that only certain clients receive certain messages. The decoupling has three dimensions: Space, Time, Synchronization.
Filtración de mensajes
So what’s interesting is, how does the broker filter all messages, so each subscriber only gets the messages it is interested in? Option 1: Subject-based filtering
The filtering is based on a subject or topic, which is part of each message. The receiving client subscribes on the topics it is interested in with the broker and from there on it gets all message based on the subscribed topics. Topics are in general strings with an hierarchical structure, that allow filtering based on a limited number of expression.
Option 2: Content-based filtering
Content-based filtering is as the name already implies, when the broker filters the message based on a specific content filter-language. Therefore clients subscribe to filter queries of messages they are interested in. A big downside to this is, that the content of the message must be known beforehand and can not be encrypted or changed easily.
Option 3: Type-based filtering
When using object-oriented languages it is a common practice to filter based on the type/class of the message (event). In this case a subscriber could listen to all messages, which are from type Exception or any subtype of it.
Of course publish/subscribe is not a silver bullet and there are some things to consider, before using it. The decoupling of publisher and subscriber, which is the key in pub/sub, brings a few challenges with it. You have to be aware of the structuring of the published data beforehand. In case of subject-based filtering, both publisher and subscriber need to know about the right topics to use. Another aspect is the delivery of message and that a publisher can’t assume that somebody is listening to the messages he sends. Therefore it could be the case that a message is not read by any subscriber.
Cliente
When talking about a client it almost always means an MQTT client. This includes publisher or subscribers, both of them label an MQTT client that is only doing publishing or subscribing. (In general a MQTT client can be both a publisher & subscriber at the same time). A MQTT client is any device from a micro controller up to a full fledged server, that has a MQTT library running and is connecting to an MQTT broker over any kind of network, basically any device that has a TCP/IP stack and speaks MQTT over it. The client implementation of the MQTT protocol is very straight-forward and really reduced to the essence. That’s one aspect, why MQTT is ideally suitable for small devices. MQTT client libraries are available for a huge variety of programming languages, for example Android, Arduino, C, C++, C#, Go, iOS, Java, JavaScript, .NET.
Broker
The counterpart to a MQTT client is the MQTT broker, which is the heart of any publish/subscribe protocol. Depending on the concrete implementation, a broker can handle up to thousands of concurrently connected MQTT clients. The broker is primarily responsible for receiving all messages, filtering them, decide who is interested in it and then sending the message to all subscribed clients. It also holds the session of all persisted clients including subscriptions and missed messages. Another responsibility of the broker is the authentication and authorization of clients. And at most of the times a broker is also extensible, which allows to easily integrate custom authentication, authorization and integration into backend systems. Especially the integration is an important aspect, because often the broker is the component, which is directly exposed on the internet and handles a lot of clients and then passes messages along to downstream analyzing and processing systems.
Un ejemplo de un broker es Mosquitto.
Métodos
CONNECT
The MQTT protocol is based on top of TCP/IP and both client and broker need to have a TCP/IP stack.
The MQTT connection itself is always between one client and the broker, no client is connected to another client directly. The connection is initiated through a client sending a CONNECT message to the broker. The broker response with a CONNACK and a status code. Once the connection is established, the broker will keep it open as long as the client doesn’t send a disconnect command or it looses the connection.
Client initiates connection with the CONNECT message
So let’s look at the MQTT CONNECT command message. As already mentioned this is sent from the client to the broker to initiate a connection. If the CONNECT message is malformed (according to the MQTT spec) or it takes too long from opening a network socket to sending it, the broker will close the connection. This is a reasonable behavior to avoid that malicious clients can slow down the broker. A good-natured client will send a connect message with the following content among other things:
In the following table you see all return codes at a glance.
Return Code | Return Code Response |
---|---|
0 | Connection Accepted |
1 | Connection Refused, unacceptable protocol version |
2 | Connection Refused, identifier rejected |
3 | Connection Refused, Server unavailable |
4 | Connection Refused, bad user name or password |
5 | Connection Refused, not authorized |
PUBLISH
After a MQTT client is connected to a broker, it can publish messages. MQTT has a topic-based filtering of the messages on the broker, so each message must contain a topic, which will be used by the broker to forward the message to interested clients. Each message typically has a payload which contains the actual data to transmit in byte format. MQTT is data-agnostic and it totally depends on the use case how the payload is structured. It’s completely up to the sender if it wants to send binary data, textual data or even full-fledged XML or JSON. A MQTT publish message also has some more attributes, which we’re going discuss in detail:
Topic Name
A simple string, which is hierarchically structured with forward slashes as delimiters. An example would be “myhome/livingroom/temperature”.
QoS
A Quality of Service Level (QoS) for this message. The level (0,1 or 2) determines the guarantee of a message reaching the other end (client or broker).
Retain-Flag
This flag determines if the message will be saved by the broker for the specified topic as last known good value. New clients that subscribe to that topic will receive the last retained message on that topic instantly after subscribing.
Payload
This is the actual content of the message. MQTT is totally data-agnostic, it’s possible to send images, texts in any encoding, encrypted data and virtually every data in binary.
Packet Identifier
The packet identifier is a unique identifier between client and broker to identify a message in a message flow. This is only relevant for QoS greater than zero. Setting this MQTT internal identifier is the responsibility of the client library and/or the broker.
DUP flag
The duplicate flag indicates, that this message is a duplicate and is resent because the other end didn’t acknowledge the original message. This is only relevant for QoS greater than 0. This resend/duplicate mechanism is typically handled by the MQTT client library or the broker as an implementation detail. So when a client sends a publish to a MQTT broker, the broker will read the publish, acknowledge the publish if needed (according to the QoS Level) and then process it. Processing includes determining which clients have subscribed on that topic and then sending out the message to the selected clients which subscribe to that topic.
The client, who initially published the message is only concerned about delivering the publish message to the broker. From there on it is the responsibility of the broker to deliver the message to all subscribers. The publishing client doesn’t get any feedback, if someone was interested in this published message and how many clients received the message by the broker.
SUBSCRIBE
Publishing messages doesn’t make sense if there are no clients subscribing to any topic. A client needs to send a SUBSCRIBE message to the MQTT broker in order to receive relevant messages. A subscribe message is pretty simple, it just contains a unique packet identifier and a list of subscriptions.
Packet Identifier
This is the same as the one used in the Publish message.
List of Subscriptions
A SUBSCRIBE message can contain an arbitrary number of subscriptions for a client. Each subscription is a pair of a topic topic and QoS level. The topic in the subscribe message can also contain wildcards, which makes it possible to subscribe to certain topic patterns. If there are overlapping subscriptions for one client, the highest QoS level for that topic wins and will be used by the broker for delivering the message.
SUBACK
Each subscription will be confirmed by the broker through sending an acknowledgment to the client in form of the SUBACK message. This message contains the same packet identifier as the original Subscribe message (in order to identify the message) and a list of return codes.
Packet Identifier
The packet identifier is a unique identifier used to identify a message. It is the same as in the SUBSCRIBE message.
Return Code
The broker sends one return code for each topic/QoS-pair it received in the SUBSCRIBE message. So if the SUBSCRIBE message had 5 subscriptions, there will be 5 return codes to acknowledge each topic with the QoS level granted by the broker. If the subscription was prohibited by the broker (e.g. if the client was not allowed to subscribe to this topic due to insufficient permission or if the topic was malformed), the broker will respond with a failure return code for that specific topic.
Return Code | Return Code Response |
---|---|
0 | Success – Maximum QoS 0 |
1 | Success – Maximum QoS 1 |
2 | Success – Maximum QoS 2 |
128 | Failure |
After a client successfully sent the SUBSCRIBE message and received the SUBACK message, it will receive every published message matching the topic of the subscription.
UNSUBSCRIBE
The counterpart of the SUBSCRIBE message is the UNSUBSCRIBE message which deletes existing subscriptions of a client on the broker. The UNSUBSCRIBE message is similar to the SUBSCRIBE message and also has a packet identifier and a list of topics.
Packet Identifier
The packet identifier is a unique identifier used to identify a message. The acknowledgement of an UNSUBSCRIBE message will contain the same identifier.
List of Topic
The list of topics contains an arbitrary number of topics, the client wishes to unsubscribe from. It is only necessary to send the topic as string (without QoS), the topic will be unsubscribed regardless of the QoS level it was initially subscribed with.
UNSUBACK
The broker will acknowledge the request to unsubscribe with the UNSUBACK message. This message only contains a packet identifier.
Artículos relacionados
Ligas externas
Página oficial de MQTT http://mqtt.org/
Documentación oficial MQTT v3.1.1 http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html