Các thành phần cơ bản của MQTT: Client (Publisher/Subscriber), Server (Broker), Sessions (Phiên làm việc), Subscription và Topic.
Thành phần chính của MQTT là Client (Publisher/Subscriber), Server (Broker), Sessions (Phiên làm việc), Subscription và Topic.
Hình 3.15 Kiến trúc giao thức MQTT
Để làm việc với MQTT ta cần ít nhất các gói tin cơ bản gồm gói Connect, Subcribe và Public, việc trao đổi các gói tin giữa Client và Broker được minh họa như hình 3.5. Cấu trúc một gói tin chuẩn của MQTT được minh họa ở hình 3.6.
Hình 3.16 Luồng trao đổi tin trong MQTT
Hình 3.17 Cấu trúc chuẩn một gói tin MQTT
Bảng 3.8 Mô tả loại message từ bít 7-4 của byte 1
Từ gợi nhớ | Giá trị thứ tự | Miêu tả |
Reserved | 0 | Chưa dùng |
CONNECT | 1 | Client yêu cầu kết nối đến Server |
CONNACK | 2 | Kết nối được chấp nhận |
PUBLISH | 3 | Xuất bản message |
PUBACK | 4 | Xuất bản message được chấp nhận |
PUBREC | 5 | Xuất bản đã được nhận |
PUBREL | 6 | Xuất bản release |
PUBCOMP | 7 | Xuất bản hoàn thành |
SUBSCRIBE | 8 | Yêu cầu subcribe từ client |
SUBACK | 9 | Yêu cầu subcriber được chấp nhận |
UNSUBSCRIBE | 10 | Yêu cầu unsubcribe |
UNSUBACK | 11 | Yêu cầu unsubcribe được chấp nhận |
PINGREQ | 12 | Request PING |
PINGRESP | 13 | Response PING |
DISCONNECT | 14 | Client đang mất kết nối |
Reserved | 15 | Reserved |
Cờ này được bật khi client hoặc server đang cố chuyển lại một gói PUBLISH, PUBREL, SUBSCRIBE or UNSUBSCRIBE. Giá trị này được sử dụng trong các mesage mà có QoS lớn hơn 0 và yêu cầu ACK. Khi bit DUP được set, phần header thay đổi sẽ là Message ID.
Phía nhận xem giá trị này là một gợi ý để tự kiểm tra xem gói tin (có Message ID) ở trên đã chuyển đến trước đó hay không. Còn chỉ từ trạng thái cờ DUP này thì chưa thể chắc chắn có gói tin lặp được.
Qos 0: Client gửi Publish tới Server không cần quan tâm đến gói tin gửi.
Qos 1: Client gửi Publish tới Server, sau đó nếu Server nhận được gói tin và gửi lại Client gói PUBACK để xác nhận đã nhận được gói Publish từ Client.
Qos 2: Client gửi Publish tới Server, Server nhận gói Publish gửi PUBREC lại Client kèm theo ID đã nhận. Client nhận PUBREC gửi PUBREL kèm ID đó lại Server. Server gửi lại PUBCOMP lại Client.
Cờ này chỉ được sử dụng ở message PUBLISH.
Khi client gửi 1 message PUBLISH đến server, nếu cờ Retain được set (1), thì server phải hiểu rằng phải giữ message này sau khi chuyển nó đến các subcribers hiện tại.
Khi có 1 subcription mới được thiết lập đến 1 topic, message cuối cùng được lưu lại của topic đó phải được gửi đến subscriber và trường Retain được set (1) trong phần header. Nếu không có messsage nào của topic được lưu giữ, thì không cần gửi gì hết.
Trường hợp mà server chuyển tiếp nội dung vừa nhận được từ một Publisher thì trường Retain sẽ không được set. Điều này sẽ giúp phân biệt được message có từ trước với message mới được publish lên.
Message Retained sẽ được giữ thậm chí sau khi restart lại server
Server sẽ xóa message được retained nếu nó nhận đựoc một message với payload bằng zero.
Miêu tả độ dài bao gồm cả phần “variable length header” và “payload” có trong message (không tính độ dài packet length).
Phần này không cố định số byte, tối đa 4 byte và tối thiểu 1 byte. Bít cao nhất của byte sẽ xác định xem byte phía sau nó có thuộc “Packet length”, 7 bít được dùng để miêu tả giá trị.
Bảng 3.9 Mô tả lượng byte có thể được mã hóa dựa vào số byte Packet length
Số byte | Nhỏ nhất | Lớn nhất |
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) |
Ví dụ 1: Gói tin phía sau còn 321 byte, thì ta cần 2byte cho packet lenghth với byte 1 là byte thấp và byte 2 là byte cao. Bít cao nhất của byte 1 phải được bật lên 1 để báo còn 01 byte 2. Ta có: 321 = 65 + 2*2^7 = 1000001B + 0000010B*2^7
bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Byte 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
Byte 2 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
Vậy: Packet length = 0xC1 0x02 (Hex)
Một số gói tin điều khiển trong MQTT có thành phần “Variable lenghth hearder” nhưng không phải lúc nào cũng có trong các gói tin MQTT. Một số gói tin hoặc lệnh trong MQTT yêu cầu thành phần “Variable lenghth hearder” mang thông tin bổ sung. “Variable lenghth hearder” nằm giữa “packet length” và “payload”. “Variable lenghth hearder” sẽ khác nhau tùy thuộc vào loại gói tin.
Là trường chứa các thông tin phục vụ việc connect như Clinet ID, user, pass và là thành phần cuối của gói tin, nhưng không phải lúc nào cũng có trong các gói tin MQTT. Bảng 3.10 mô tả các gói tin có chứa thành phần Payload.
Bảng 3.10 Gói tin điều khiển có chứa payload
Control Packet | Payload | Control Packet | Payload |
CONNECT | Required | SUBSCRIBE | Required |
CONNACK | None | SUBACK | Required |
PUBLISH | Optional | UNSUBSCRIBE | Required |
PUBACK | None | UNSUBACK | None |
PUBREC | None | PINGREQ | None |
PUBREL | None | PINGRESP | None |
PUBCOMP | None | DISCONNECT | None |
Chi tiết định dạng các gói tin vui lòng tham khảo thêm ở tài liệu “MQTT Version 3.1.1” để có thể sử dụng