1. Describes the MQTT protocol

1.1 the MQTT protocol

MQTT (Message Queue Telemetry Transmission) is a messaging protocol based on TCP/IP protocol stack to support asynchronous communication between parties. MQTT separates the sender from the receiver spatially and spatially, so it can scale in an unreliable network environment. Although called message queue telemetry transport, it has nothing to do with message queues and uses a publish and subscribe (Pub/Sub) model.

MQTT is a lightweight, flexible networking protocol dedicated to achieving the right balance for IoT developers:

  • This lightweight protocol can be implemented over severely limited device hardware and high latency/limited bandwidth networks.
  • Its flexibility makes it possible to support diverse application scenarios for IoT devices and services.

1.2 the MQTT Client library

The MQTT Client library is implemented in many languages, including Embedded C, C, Java, JavaScript, Python, C++, C#, Go, iOS, Android, etc. Eclipse Paho MQTT library download address: www.eclipse.org/paho/downlo…

The following development practices based on Nodejs version MQTT, access the address www.npmjs.com/package/mqt…

1.3 the MQTT messages

1.3.1 Fixed header

Bit
7
6
5
4
3
2
1
0
byte 1
MQTT Controls the type of packets
Flag bit used to specify the type of control message
Byte 2 5-tetrafluorobenzoic
Remaining length, maximum 4 bytes

Control message Type

The name value Direction of packet Flow describe
Reserved 0 ban keep
CONNECT 1 Client -> Broker Device Connects to the IoT platform
CONNACK 2 Broker -> Client The IoT platform confirms the connection result
PUBLISH 3 two-way news
PUBACK 4 two-way QoS=1 Indicates that the message is received
PUBREC 5 two-way IoT is not supported
PUBREL 6 two-way IoT is not supported
PUBCOMP 7 two-way IoT is not supported
SUBSCRIBE 8 Client -> Broker Device subscribes to IoT Platform Topic
SUBACK 9 Broker -> Client IoT platform confirms subscription results
UNSUBSCRIBE 10 Client -> Broker Device unsubscribes to IoT Platform Topic
UNSUBACK 11 Broker -> Client IoT platform confirms the result of unsubscription
PINGREQ 12 Client -> Broker The device sends a heartbeat request to the IoT platform
PINGRESP 13 Broker -> Client The IoT platform responds to the device heartbeat
DISCONNECT 14 Client -> Broker Device Disconnects from the IoT platform
Reserved 15 ban keep

Flag bit that controls the packet type

Control message Fixed masthead logo Bit 3 Bit 2 Bit 1 Bit 0
PUBLISH MQTT 3.1.1 use DUP QoS QoS RETAIN

The length of the remaining

The number of bytes The minimum value The maximum
1 0 (0x00) 127 (0x7F)
2 128 (0x80, 0x01) 16 383 (0xFF, 0x7F)
3 16 384 (0x80, 0x80, 0x01) 2 097 151 (0xFF, 0xFF, 0x7F)
4 2 097 152 (0x80, 0x80, 0x80, 0x01) 268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)

Note: The maximum payload of aliyun IoT is 256K

1.3.2 Variable Header

Some MQTT control messages contain a variable header section. It is between the fixed header and the load. The content of the mutable header varies according to the message type. The variable header Packet Identifier field exists in multiple types of packets.

Packet Identifier Bytes
Bit 7 – 0
byte 1 Message identifier MSB
byte 2 Packet identifier LSB
Control message Message identifier
PUBLISH Required (if QoS = 1,2)
PUBACK Need to be
PUBREC Need to be
PUBREL Need to be
PUBCOMP Need to be
SUBSCRIBE Need to be
SUBACK Need to be
UNSUBSCRIBE Need to be
UNSUBACK Need to be

1.3.3 Payload

The following MQTT control message contains a payload at the end of the message. For PUBLISH, the payload is a business message.

Control message The payload
CONNECT Need to be
PUBLISH optional
SUBSCRIBE Need to be
SUBACK Need to be
UNSUBSCRIBE Need to be

2. Establish a connection with Aliyun IoT platform

2.1 the CONNECT

MQTT protocol of Aliyun IoT platform does not support will message, and the content parameters of CONNECT message are as follows:

parameter
instructions
cleanSession
This flag specifies whether the connection is persistent.
0 indicates a persistent session, and the message will not be lost if QoS=1.
1 indicates a non-persistent session and clears offline messages.
clientId
Client identifier
username
Authentication and authorization credentials for the agent.
password
Authentication and authorization credentials for the agent.
keepAlive
Heartbeat time. The heartbeat range of the IoT platform is 30 seconds to 1200 seconds

ClientId, username, password by equipment triples (productKey, deviceName, deviceSecret) generated in accordance with the rules, the specific rules are as follows:

clientId
id+”|securemode=3,signmethod=hmacsha1,timestamp=”+timestamp+”|”
Id: indicates the client ID. The value is a string of 64 characters. The | | to extension within parameters.
Securemode: securemode. 2 indicates TLS encryption, and 3 indicates non-encryption
Signmethod: indicates the type of the signature algorithm. Timestamp: milliseconds of the current time.
username
deviceName+”&”+productKey
password
sign_hmac(deviceSecret,content)
Sign_hmac indicates the signmethod algorithm type in clientId
Content: “clientId${ID}deviceName${deviceName}productKey${productKey}timestamp${timestamp}”

Official documentation: help.aliyun.com/document_de…

Device-side code example (Nodejs version) client.js

/**
"dependencies": { "mqtt": "2.18.8" }
*/
const crypto = require('crypto');
const mqtt = require('mqtt');
// Device identity triplet + region
const deviceConfig = {
    productKey: "Replacement".deviceName: "Replacement".deviceSecret: "Replacement".regionId: "cn-shanghai"
};
// Generate MQTT connection parameters based on triples
const options = initMqttOptions(deviceConfig);
const url = `tcp://${deviceConfig.productKey}.iot-as-mqtt.${deviceConfig.regionId}.aliyuncs.com:1883`;

//2. Establish a connection
const client = mqtt.connect(url, options);

client.on('packetsend'.function (packet){
  console.log('send '+packet.cmd+' packet =>',packet)
})

client.on('packetreceive'.function (packet){
  console.log('receive '+packet.cmd+' packet =>',packet)
})


//IoT platform MQTT connection parameters initialized
function initMqttOptions(deviceConfig) {

    const params = {
        productKey: deviceConfig.productKey,
        deviceName: deviceConfig.deviceName,
        timestamp: Date.now(),
        clientId: Math.random().toString(36).substr(2),}/ / CONNECT parameters
    const options = {
        keepalive: 60.//60s
        clean: false.//cleanSession keeps the conversation going
        protocolVersion: 4 / / the MQTT v3.1.1
    }
    //1. Generate clientId, username, password
    options.password = signHmacSha1(params, deviceConfig.deviceSecret);
    options.clientId = `${params.clientId}|securemode=3,signmethod=hmacsha1,timestamp=${params.timestamp}| `;
    options.username = `${params.deviceName}&${params.productKey}`;

    return options;
}

/ * generated password based on HmacSha1 reference documentation: https://help.aliyun.com/document_detail/73742.html?#h2-url-1 * /
function signHmacSha1(params, deviceSecret) {

    let keys = Object.keys(params).sort();
    // Sort by lexicographical order
    keys = keys.sort();
    const list = [];
    keys.map((key) = > {
        list.push(`${key}${params[key]}`);
    });
    const contentStr = list.join(' ');
    return crypto.createHmac('sha1', deviceSecret)
            .update(contentStr)
            .digest('hex');
}
Copy the code

2.2 CONNACK

receive connack packet => Packet {
  cmd: 'connack'.retain: false.qos: 0.dup: false.length: 2.topic: null.payload: null.sessionPresent: false.returnCode: 0 
}
Copy the code

2.4 PINGRESP

send pingreq packet => { cmd: 'pingreq' }
Copy the code

2.5 PINGRESP

receive pingresp packet => Packet {
  cmd: 'pingresp'.retain: false.qos: 0.dup: false.length: 0.topic: null.payload: null 
}
Copy the code

2.6 DISCONNECT

3. Publish data

3.1 the PUBLISH

//3. Attribute data reporting
const topic = `/sys/${deviceConfig.productKey}/${deviceConfig.deviceName}/thing/event/property/post`;
setInterval(function() {
    // Publish data to topic
    client.publish(topic, getPostData(),{qos:1});
}, 5 * 1000);

function getPostData() {
    const payloadJson = {
        id: Date.now(),
        params: {
            temperature: Math.floor((Math.random() * 20) + 10),
            humidity: Math.floor((Math.random() * 20) + 60)},method: "thing.event.property.post"
    }

    console.log("===postData\n topic=" + topic)
    console.log(payloadJson)

    return JSON.stringify(payloadJson);
}

Copy the code
send publish packet => { cmd: 'publish'.topic: '/sys/a1hQSwFledE/eud1jXfEgCsAiP2eId9Q/thing/event/property/post'.payload: '{"id":1543896481106,"params":{"temperature":23,"humidity":73},"method":"thing.event.property.post"}'.qos: 1.retain: false.messageId: 38850.dup: false 
}
Copy the code

3.2 PUBACK

receive puback packet => Packet {
  cmd: 'puback'.retain: false.qos: 0.dup: false.length: 2.topic: null.payload: null.messageId: 38850 
}
Copy the code

4. Receive data

4.1 the SUBSCRIBE

//4. Subscribe to the topic and receive instructions
const subTopic = ` /${deviceConfig.productKey}/${deviceConfig.deviceName}/control`;
client.subscribe(subTopic)
client.on('message'.function(topic, message) {
    console.log("topic " + topic)
    console.log("message " + message)
})
Copy the code

The SUBSCRIBE message body

send subscribe packet => { cmd: 'subscribe'.subscriptions: [{topic: '/a1hQSwFledE/eud1jXfEgCsAiP2eId9Q/control'.qos: 0}].qos: 1.retain: false.dup: false.messageId: 38851 
}
Copy the code

4.2 SUBACK

SUBACK message body

receive suback packet => Packet {
  cmd: 'suback'.retain: false.qos: 0.dup: false.length: 3.topic: null.payload: null.granted: [ 128].messageId: 38851 
}
Copy the code

4.3 UNSUBSCRIBE

send unsubscribe packet => { cmd: 'unsubscribe'.qos: 1.messageId: 34323.unsubscriptions: [ '/a1hQSwFledE/eud1jXfEgCsAiP2eId9Q/control']}Copy the code

4.4 UNSUBACK

receive unsuback packet => Packet {
  cmd: 'unsuback'.retain: false.qos: 0.dup: false.length: 2.topic: null.payload: null.messageId: 34323 
}
Copy the code

5. Quality of service QoS

The quality of service
Quality of Service
describe
Ali cloud IoT
QoS=0
At most one transmission, the message may not be received
support
QoS=1
For at least one transmission, a message must be received, possibly repeated
support
QoS=2
There is one and only one transfer
Does not support

6. The device is disconnected and reconnected

The subscription relationship between the device and Ali Cloud IoT is maintained in the cloud, unless the device actively unsubscribe, the subscription relationship will not be cleared. After the device is reconnected, the subscription relationship remains, and the subscription does not need to be repeated.

7. Transport layer security TLS1.2

The link between the device and the IoT platform can be encrypted using TLS V1.2. If TLS encryption is used, you need to download the root certificate. In the CONNECT parameter, the Securemode of clientId is 2

Help.aliyun.com/document_de…

IoT technology