IoT protocol MQTT

IoT protocol MQTT

1. Introduction to MQTT

  MQTT (Message Queuing Telemetry Transport) is a messaging protocol based on the publish/subscribe paradigm under the ISO standard (ISO/IEC PRF 20922) . It works on the TCP/IP protocol family and is a publish/subscribe message protocol designed for remote devices with low hardware performance and poor network conditions. For this reason, it needs a message middleware.
  MQTT is a client-server based message publish/subscribe transport protocol . Released by IBM in 1999. The MQTT protocol is lightweight, simple, open and easy to implement. These characteristics make it widely applicable. In many cases, including constrained environments, as a low-overhead, low-bandwidth instant messaging protocol , it has wider applications in the Internet of Things, small devices, mobile applications, etc. Such as: machine-to-machine (M2M) communication and Internet of Things (IoT). It is used extensively in sensors communicating via satellite links, medical devices that occasionally dial, smart homes, and some miniaturized devices.
  The biggest advantage of MQTT is that it provides real-time and reliable message services for connected remote devices with very little code and limited bandwidth.
insert image description here

2. MQTT features

  This protocol runs over TCP/IP, or other network connections that provide ordered, reliable, bidirectional connections. MQTT belongs to the application layer protocol , which has the following characteristics:

  • Using the publish/subscribe message pattern, it provides one-to-many message distribution and decoupling between applications.
  • Message transmission does not need to know the payload content.
  • Three levels of quality of service are provided: .
  • QS0: "At most once" , the message is distributed as best as the operating environment can provide. Messages may be lost. For example, this level can be used for environmental sensor data, where a single loss of data is okay because it will be sent again shortly thereafter.
  • QS1: "At least once" , the message is guaranteed to arrive, but may be repeated.
  • QS2: "Only once" , guarantees that the message arrives only once. For example, this level could be used in a billing system where duplicate or missing messages would result in incorrect billing. Small transmission consumption and protocol data exchange minimize network traffic.

3. MQTT control message

  The MQTT protocol communicates by exchanging predefined MQTT control messages. The MQTT control message consists of three parts: Fixed header, Variable header, and Payload.

Fixed header fixed header , all control packets contain
Variable header variable header , part of the control message contains
Payload payload , part of the control message contains

3.1 Fixed header format

insert image description here

  • Control message type
    insert image description here

3.2 MQTT control message type set flag

The upper 4 bits (4 ~ 7)   of the first byte of the fixed header are the control message type, a total of 14, and the lower 4 bits (0 ~ 3) contain the specific flags of each MQTT control message type, see the table below. Any flags marked "reserved" in the table are reserved for future use and must be set to the values ​​listed in the table. If an invalid flag is received, the receiver MUST close the network connection.
insert image description here
  DUP1 = Duplicate distribution flag for control packets.
  QoS2 = Quality of service class for PUBLISH packets.
  RETAIN3 = Retention flag for PUBLISH message.
  DUP, QoS and RETAIN flags in the PUBLISH control message.
  For details, refer to the MQTT3.1 protocol.

3.3 Calculation of remaining length

  Remaining Length Indicates the number of bytes in the remaining part of the current message, including variable header and payload data. The remaining length does not include the number of bytes used to encode the remaining length field itself.
  The remaining length field uses a variable-length encoding scheme, and for values ​​less than 128 it uses a single-byte encoding. Larger values ​​are handled as follows. The least significant 7 bits are used to encode the data8 and the most significant bit is used to indicate if there are more bytes. That is, the remaining length is counted in 128 system, and the maximum remaining length field is 4 bytes .

  • The value of the remaining length field is as follows:
    insert image description here
      the remaining length is counted in hexadecimal, and expressed in hexadecimal, with the low byte first. Example of remaining length encoding:
      ① For example, 64: (64/128) rounding = 0, indicating that 64 does not need to be carried, and 1 byte can be represented, that is: 0x40;
      ② For example, 456: (456/128) rounding = 3 , (3/128) rounding = 0, indicating that 456 needs 2 bytes to represent.
       The first byte bit7=1, (bit0~bit6)=456%128=72=0x48, that is, the first byte is expressed as: 0xc8; the second byte
       bit7=3/128=0, (bit0~ bit6)=3%128=3, that is, the second byte represents the bit: 0x3;
       in summary, 456 is represented by 2 bytes: 0xc8 0x3;
      ③For example, 100000: (100000/128)=781, (781/ 128)=6, indicating that 100000 needs 3 bytes to indicate
       the first byte bit7=1, (bit0~bit6)=100000%128=0x20, that is, the first byte is 0xa0; the second byte
       bit7=1 , (bit0~bit6)=781%128=0x0d, that is, the second byte is 0x8d; the third byte
       bit7=0, (bit0~bit6)=6%128=6, that is, the third byte is 0x6;
       To sum up, 100000 is represented by 3 bytes: 0xa0 0x8d 0x6;

3.4 C language implementation example of remaining length calculation

  • remaining length encoding
int MQTT_RemainSum(int data,u8 buff[])
{
    
    
	int cnt=0;//记录编码的字节数
	do
	{
    
    
		u8 encodedByte = data % 128;
		data/=128;
		if(data>0)
		{
    
    
			//若data超过128,则将最最高位置1
			encodedByte=encodedByte|=0x80;
		}
		buff[cnt++]=encodedByte;
		
	}while(data>0);
	return cnt;//返回需要编码的字节数个数
}
  • Residual length decoding
int MQTT_remainGet(u8 buff[],int cnt)
{
    
    
	int data=0;
	int i=0;
	int count=1;
	for(;i<cnt;i++)
	{
    
    
		data+=(buff[i]&0x7f)*count;
		count<<=7;
	}
	return data;
}
  • Test example:
int main(int argc,char *argv[])
{
    
    
	if(argc!=2)
	{
    
    
		printf("格式:./a.out <剩余长度>\n");
		return 0;
	}
	int data=atoi(argv[1]);
	u8 buff[4];
	int cnt=MQTT_RemainSum(data,buff);
	for(int i=0;i<cnt;i++)
	{
    
    
		printf("%#x ",buff[i]);
	}
	printf("\n");
	printf("data=%d\n", MQTT_remainGet(buff,cnt));
}
[wbyq@wbyq work]$ ./a.out 64
0x40 
data=64
[wbyq@wbyq work]$ ./a.out 456
0xc8 0x3 
data=456
[wbyq@wbyq work]$ ./a.out 100000
0xa0 0x8d 0x6 
data=100000
[wbyq@wbyq work]$ ./a.out 268435455
0xff 0xff 0xff 0x7f 
data=268435455

4. MQTT message level

  • MQTT provides three levels of service quality
  • QS0: "At most once" , the message is distributed as best as the operating environment can provide. Messages may be lost. For example,
    this level can be used for environmental sensor data, where a single loss of data is okay because it will be sent again shortly thereafter.
  • QS1: "At least once" , the message is guaranteed to arrive, but may be repeated.
  • QS2: "Only once" , guarantees that the message arrives only once. For example, this level could be used in a billing system where duplicate or missing messages would result in incorrect billing. Small transmission consumption and protocol data exchange minimize network traffic.
    insert image description here
      PUBLISH packets cannot set all QoS bits to 1. If the server or client receives a PUBLISH packet with all QoS bits set to 1, it MUST close the network connection.
  • Qos0 at most once

  The sender sends the message only once, without retrying . The semantics of retransmissions are also not defined in the protocol. The message may reach the server 1 time, or it may not arrive at all.
insert image description here

  • Qos1 at least once

  Receipt of the message by the server is acknowledged by transmitting a PUBACK message. If there is an identifiable transmission failure, whether it is the communication link or the sending device, or if the confirmation message has not been received after a period of time, the sender will set the DUP bit of the message header to 1, and then send the message again. Messages arrive at the server at least once.
  If the client does not receive the PUBACK message (whether it is an application-defined timeout, or a failure is detected and the communication session is restarted), the client will send the PUBLISH message again and set the DUP bit to 1.
  When it receives duplicate data from the client, the server resends the message to the subscriber and sends another PUBACK message.
insert image description here

  As shown in the figure above, in order to ensure that the Qos1 message level is delivered at least once , the publisher will temporarily store the sent message locally and resend it at regular intervals until the receiver returns a reply. When we receive the response, we can delete the temporary message and stop retransmission.
  For the receiver, you need to reply every time you receive a message. In the above figure, publisher (publisher) to broker (agent, server) and broker (agent, server) to subscriber (subscriber) are equivalent, and both communication should be implemented as discussed above.

  • Qos2 only once
    insert image description here
      QS2 message level guarantees that the message must arrive once , the publisher (publisher) to the broker (agent, server) and the broker (agent, server) to subscriber (subscriber) are equal, and the two communications are the same grade. The specific message transmission process is as follows:
      1. The publisher sends a message and temporarily stores the message content locally.
      2. After receiving the message content, the receiver temporarily stores the message content locally, and replies with a response (PUBREC) to the sender. The publisher will resend the message once in a while before receiving the PUBREC to ensure that the message is consistent. can be delivered.
      3. When the publisher receives the PUBREC, it stops resending the message and sends the content of the release (PUBREL) message to the receiver. After receiving the PUBREL, the receiver can confirm that the message transmission is successful.
      4. Delete the temporarily stored message, and then the sender will directly send a PUBREL message to the receiver every time it receives PUBREC.
      5. After receiving the PUBREL message, the receiving end modifies the temporarily stored message status to publish complete, stops sending PUBREC, and then sends a publish complete (PUBCOM) message to the sending end. At this time, the receiving end will delete the temporarily stored message, and then reply PUBCOM directly every time it receives PUBREL.
      6. When the sending end receives PUBCOM, if it finds that the temporarily stored message is still deleted every time, it will delete the temporarily stored message, and if it has been deleted, it will be ignored.
      Notice:During this process, the function of the local temporary storage message is to achieve deduplication when receiving duplicate content. After receiving PUBREL, it can be determined that the sender will no longer send this message, so the temporary storage message can be deleted at this time. , similarly, after receiving PUBREC, the sending end knows that the receiving end has received the message, so there is no need to send the message, and the temporary storage can be deleted.

Guess you like

Origin blog.csdn.net/weixin_44453694/article/details/127908102