Tech

IOT: giao thức MQTT

How MQTT Works

Cơ bản về giao thức MQTT, tại sao nó hiệu quả với các thiết bị IOT và sơ lược về bảo mật MQTT

Photo: medium.com
17 phút để đọc hết nội dung

Bài viết này dành cho các bạn muốn tìm hiểu thêm về giao thức MQTT, vốn được sử dụng rộng rãi bởi các thiết bị IOT – Internet vạn vật. Trong bài viết này chúng tôi sẽ cố gắng làm rõ cách hoạt động cũng như một số khái niệm và thành phần tạo nên một mạng lưới hoạt động qua giao thức MQTT. Nếu bạn là người dùng thông thường, mới tìm hiểu về Smarthome/IOT và có thắc mắc hay rắc rối liên quan đến giao thức MQTT, chúng tôi hi vọng bài viết này sẽ giúp làm sáng tỏ một số vấn đề.

Từ khoá: ClientID / Broker / Topic, Payload, Retained / LWT / Bridge / Mosquitto / ACL

MQTT

Theo trang web (http://)MQTT.org

MQTT là

giao thức kết nối giữa máy và máy/iot được thiết kế để vận chuyển các thông điệp siêu nhẹ, sử dụng giao thức đăng ký/xuất bản – subscribe/publish để chuyển thông điệp giữa các thiết bị trong một môi trường mà băng thông cực kỳ giới hạn. Để tối thiểu hoá băng thông cần thiết, giao thức MQTT đòi hỏi rất ít code footprint – dấu nhận dạng, thường đi kèm với mỗi thông điệp/gói tin để định danh giao thức. Mặc dù thường được sử dụng trên nền kết nối TCP/IP, bất cứ giao thức kết nối nào hỗ trợ thứ tự, toàn vẹn dữ liệu và giao tiếp hai chiều đều có thể hỗ trợ MQTT.

MQTT được phát minh từ năm 1999 bởi TS. Andy Stanford-Clark từ IBM, và Arlen Nipper từ Arcom (nay là EuroTech), ban đầu với mục đích giám sát các ống dẫn dầu đi qua sa mạc thông qua kết nối vệ tinh vốn có giá băng thông cực kì đắt đỏ vào thời đó, sử dụng các thiết bị chạy pin dọc theo đường ống.

Năm 2013, IBM đệ trình MQTT phiên bản 3.1 lên tổ chức OASIS – Organization for the Advancement of Structured Information Standards, một hiệp hội phi lợi nhuận toàn cầu nhằm phát triển các chuẩn mở trong lĩnh vực bảo mật, iot, công nghệ nội dung và nhiều lĩnh vực khác.

MQTT-SN (MQTT for Sensor Network) là một biến thể của MQTT 3.1 nhắm đến các thiết bị nhúng trong các mạng không TCP/IP như Zigbee.

Năm 2019, chuẩn MQTT 5.0 được công bố bởi OASIS.

MQTT Broker và MQTT Clients

Trong mô hình subscribe/publish của MQTT có hai thành phần chính: MQTT Broker và MQTT Clients, trong đó:

MQTT Broker

Đóng vai trò xác thực và duy trì kết nối, nhận, lưu trữ và phân phối các thông điệp từ client và đến client.

Một MQTT Broker có thể quản lý cùng lúc hàng trăm đến hàng ngàn MQTT Client kết nối cùng lúc.

Nói chung, MQTT Broker sẽ làm nhiệm vụ chính là trung gian vận chuyển – phát hành các thông điệp đến clients.

MQTT Network
MQTT Broker và Clients

MQTT Client

Là bất cứ thiết bị nào sử dụng một thư viện mqtt để kết nối đến một MQTT Broker thông qua một mạng như cảm biến chạy pin, thiết bị gia dụng hay một máy tính.

MQTT Client thông thường đóng cả hai vai trò publisher/subscriber tuỳ vào việc chúng gửi hay nhận các thông điệp đến/từ MQTT Broker thông qua các topic.

MQTT clientID, Topic, Payload, Qos và Retained

ClientID /Topic

MQTT Broker quản lý các clients qua ClientID, vì vậy các ClientID này cần là duy nhất cho mỗi client. Client không biết về các clientid khác trên cùng mạng, cũng không biết về địa chỉ IP hay bất cứ định danh nào khác.

Client gửi và nhận – publish/subscribe thông điệp thông qua các Topic – chủ đề. Một Client có thể publish hay subscribe vào nhiều topic (mô hình 1-n). MQTT Broker sẽ tự động phân phối bất cứ thông điệp nào được publish – xuất bản vào một topic đến tất cả Client đã subscribe vào topic này.

MQTT Topic thực chất là một chuỗi kí tự (UTF-8) được sử dụng bởi Broker để phân loại thông điệp trước khi gửi đến Client. MQTT Topic có thể bao gồm nhiều mức – level, phân cách với nhau bởi dấu gạch ‘/’, ví dụ: mysweethome/livingroom/switch/main light/status. Mỗi topic phải có ít nhất một kí tự, cho phép khoảng trống – space và có phân biệt chữ hoa và thường; ‘/’ là một topic hợp lệ.

Payload / QoS

Payload: là phần nội dung thực sự chứa dữ liệu của một thông điệp được Client gửi đến Broker hay được Broker phân phối lại cho các Client đã đăng ký. Đây cũng chính là phần dữ liệu các Client khác nhận được khi subscribe vào cùng topic.

QoS: quality of service, mức đảm bảo. Có ba mức Qos chính:
Qos 0: đảm bảo thông điệp gửi đi sẽ đến đích nhiều nhất là 1 lần. Thông điệp có thể bị mất khi kết nối bị gián đoạn. Nhờ sự đảm bảo toàn vẹn dữ liệu của giao thức TCP/IP, mức Qos 0 là đủ dùng trong hầu hết trường hợp thông thường.
Qos 1: thông điệp gửi đi đảm bảo sẽ đến đích nhưng có thể bị trùng lắp.
Qos 2: thông điệp gửi đi đảm bảo đến đích và chỉ đúng 1 lần. Mức Qos 2 và Qos 1 thường được sử dụng trong các môi trường mà chỉ cơ cấu TCP/IP là không đủ đảm bảo khi mà các thiết bị kết nối qua kết nối kém ổn định như Vệ Tinh (hoặc Lora).

Retained

Retained – lưu giữ: một thông điệp được đánh dấu Retained sẽ được MQTT Broker lưu trữ với đầy đủ payload và Qos. Khi đó, mọi client subscribe – đăng ký vào cùng topic sẽ nhận được thông điệp này ngay khi nó được publish và ngay khi subscribe thành công. Như vậy nếu một client liên tục bị ngắt kết nối rồi kết nối và subscribe vào topic, nó sẽ nhận được cùng một thông điệp này mọi lần subscribe thành công.
Trên mỗi topic, Broker chỉ giữ một thông điệp Retained duy nhất, thông điệp đánh dấu Retained sau sẽ thay thế cái trước. Các thông điệp không đánh dấu Retained sẽ được Broker phân phối bình thường nhưng không ảnh hưởng đến thông điệp Retained đang lưu trữ.

Một client có thể xoá bỏ thông điệp Retained trên một topic bằng cách đơn giản là publish một payload trống ” được đánh dấu Retained vào cùng topic.

LWT / Birth Message / Topic # và +

LWT – Last Will and Testament

LWT – Last Will and Testament là một tính năng của MQTT nhằm thông báo đến tất cả client khi một client khác bị mất kết nối ngoài ý muốn. Mỗi client có thể lựa chọn thông điệp và topic – Last Will Message/Topic này khi kết nối vào Broker. MQTT Broker lưu trữ thông tin này và publish đến tất cả client đã subscribe vào Last Will Topic này, trong trường hợp:

  • Broker nhận thấy một lỗi đọc ghi hoặc lỗi kết nối mạng – network failure
  • Client “im lặng” khi đã quá thời gian giữ kết nối – KeepAlive period
  • Client đóng kết nối mà không gửi dữ liệu thông báo – disconnect packet
  • Broker ngắt kết nối do lỗi giao thức

Birth Message

Birth Message, ngược lại, được sử dụng để thông báo đến tất cả client (đã subscribe) khi một client kết nối trở lại.

KeepAlive

KeepAlive: tính bằng giây, là khoảng thời gian lớn nhất để một Client và Broker giữ kết nối mà không cần giao tiếp gì với nhau. Thông thường, nếu không có thông điệp gì được gửi và nhận, Client vẫn định kỳ gửi một yêu cầu PING đến Broker, Broker cũng sẽ trả về một phản hồi PING. Nếu sau khoảng thời gian KeepAlive, không có PING nào được gửi và nhận, kết nối sẽ phải được khởi tạo lại từ đầu.

Topic wildcard

Topic #, + và $ – wildcards:

  • + thay thế cho một mức bất kì trong MQTT Topic. Ví dụ subscribe vào topic home/+/lights có nghĩa đăng ký vào mọi topic như home/living room/lights, home/bed room/lights hay home/kitchen/lights.
  • # thay thế cho mọi topic con, ở tất cả mọi mức. Subscribe vào topic home/# nghĩa là đăng ký vào mọi topic dạng home/living room/lights/1/stats, home/people hay home/alarm system/smoke.
  • $ được dành riêng để bắt đầu các topic thống kê tình trạng của Broker như $SYS/broker/clients/total, $SYS/broker/clients/total hay $SYS/broker/uptime. Topic # không bao gồm các topic $.

Bảo mật MQTT

Giao thức MQTT thực hiện xác thực thông qua cặp username/password – tên người dùng/mật khẩu. Với giao thức không mã hoá, thông tin này được gửi đi dưới dạng chữ – plain text thông thường.

Bảo mật khi truyền tải

Bảo mật phương thức truyền tải – secure transport: để tăng cường bảo mật, giao thức MQTTs áp dụng mã hoá TLS/SSL lên toàn bộ các thông tin được gửi đi (tương tự HTTPs) giữa MQTT Broker và Client, bao gồm cả tuỳ chọn yêu cầu client cung cấp chứng chỉ riêng để so sánh với chứng chỉ lưu tại Broker. Lưu ý rằng việc này sẽ gia tăng mức độ bảo mật nhưng đồng thời cũng làm tăng đáng kể dung lượng truyền tải, dẫn đến tăng thời gian phản hồi, tăng độ trễ, tăng khả năng mất tin và giảm thời lượng pin của các thiết bị.

Cổng – port mặc định của giao thức MQTT là 1883 trong khi 8883 là cổng mặc định cho giao thức MQTTs, tuy nhiên Broker có thể được cấu hình để thay đổi các cổng này.

Bảo mật network

Bảo mật mạng lưới – secure network: thực hiện giao thức MQTT thông qua các kết nối bảo mật như VPN, SSH.

Phân quyền ACL

Phân quyền Topic – MQTT ACL (access control list): MQTT Broker có thể được cấu hình để cho phép một Client chỉ được publish và subscribe vào những topic nhất định, dựa trên một danh sách gọi là ACL. Danh sách này xác định một ClientID hoặc username được quyền publish và subscribe vào những topic nào. Mặc định, ACL được thiết lập ở dạng không áp dụng hoặc cho phép tất cả trên hầu hết các MQTT Broker thông dụng.

*Không bao giờ nên xây dựng/duy trì một mạng MQTT mở và hoàn toàn không xác thực.

MQTT Bridge

Bạn có thể mở rộng hoặc gia tăng bảo mật mạng MQTT hay kết nối nhiều mạng MQTT từ các vị trí cách xa nhau bằng cách xây dựng các MQTT Bridge, đóng vai trò vừa là MQTT Broker vừa là Client để chuyển tiếp các thông điệp. Một trường hợp sử dụng thường thấy là các Client trong một khu vực kết nối đến một MQTT Broker qua giao thức MQTT không mã hoá, sau đó MQTT Broker này đóng vai trò là MQTT Bridge để chuyển tiếp các thông điệp đến một Broker khác ở xa thông qua giao thức MQTTs.

Bằng cách này, bạn có thể xây dựng một mạng MQTT với nhiều vùng riêng biệt và mở rộng không giới hạn.

Các MQTT Broker thông dụng

mosquitto mqtt

Mosquitto: miễn phí, nguồn mở. Là MQTT Broker thông dụng và rất gọn nhẹ. Được khuyến khích sử dụng bởi một số nền tảng Smarthome nguồn mở lớn như Home Assistant. Hỗ trợ MQTT 3.1 và 3.1.1, hỗ trợ websocket – ws.
Có sẵn cho nền tảng Windows, GNU/Linux, FreeBSD, Mac OS.
Đi cùng 2 MQTT Client dạng dòng lệnh là mosquitto_submosquitto_pub.

Mosca: miễn phí, nguồn mở, viết bằng ngôn ngữ JavaScript. Thường được sử dụng trong Node.js tuy nhiên có thể hoạt động độc lập. Hỗ trợ MQTT 3.1 và 3.11, hỗ trợ websocket – ws. Chỉ hỗ trợ Qos 0 và Qos 1.
Có sẵn cho các nền tảng hỗ trợ Node.js, bao gồm Windows, GNU/Linux, Mac OS.

EMQ: miễn phí, nguồn mở, viết bằng ngôn ngữ Erlang/OTP. Hỗ trợ MQTT 3.1, 3.1.1 và 5.0, hỗ trợ websocket – ws, MQTT-SN, CoAP, STOMP và SockJS.
Có sẵn cho các nền tảng Windows, GNU/Linux, FreeBSD, Mac OS.

VerneMQ: miễn phí, nguồn mở, viết bằng ngôn ngữ Erlang/OTP. Hỗ trợ MQTT 3.1, 3.1.1 và 5.0, hỗ trợ websocket – ws.
Có sẵn cho nền tảng GNU/Linux và Mac OS.

HiveMQ: giấy phép thương mại sở hữu bởi dc-square GmbH, viết bằng ngôn ngữ Java. Hỗ trợ MQTT 3.1, 3.1.1, hỗ trợ websocket – ws. Nguồn mở công bố trên github, áp dụng giấy phép Apache 2.0.

Cloudmqtt.com: không hẳn là một broker, cloudmqtt giúp bạn vận hành các Broker Mosquitto trên nền tảng đám mây – cloud thay vì server nội bộ hoặc server riêng.

Mời các bạn đón xem bài kế tiếp: Một số khuyến nghị khi triển khai MQTT và các trường hợp vận dụng, hay MQTT trong Home Assistant.

Về Bài viết

Bài viết chưa đầy đủ hoặc bạn còn có ý kiến khác? Bạn có thắc mắc và cần thêm thông tin. Vui lòng đăng ý kiến vào mục bình luận để tác giả và Team có thêm thông tin cải thiện chất lượng bài viết. Chúng tôi sẽ giải đáp các thắc mắc ngay trong mục bình luận để giúp được nhiều đọc giả với cùng vấn đề hơn hoặc chúng tôi sẽ trả lời trong một bài viết riêng. Trân trọng cảm ơn bạn!

Cảm ơn bạn đã xem bài viết này!

konnectED Team.

Lên Đầu
  • Đăng ký
Bạn quên mất mật khẩu? Vui lòng nhập tên đăng nhập và địa chỉ email đã đăng ký. Bạn sẽ nhận được liên kết tạo mật khẩu mới qua email (bạn nhớ kiểm tra hộp spam trong trường hợp email đi lạc).