MQTT là gì? Tìm hiểu tổng quan về giao thức MQTT

MQTT là gì?

MQTT (Message Queuing Telemetry Transport) là một giao thức nhắn tin tiêu chuẩn OASIS cho Internet of Things (IoT). Nó được thiết kế như một phương tiện truyền tải tin nhắn publish/subscribe (xuất bản/đăng ký) cực kỳ nhẹ, lý tưởng để kết nối các thiết bị từ xa với băng thông mạng thấp. MQTT ngày nay được sử dụng trong nhiều ngành công nghiệp, chẳng hạn như ô tô, sản xuất, viễn thông, dầu khí, v.v.

Cách MQTT hoạt động

Một phiên MQTT được chia thành bốn giai đoạn: kết nối, xác thực, giao tiếp và kết thúc. Client (máy khách) bắt đầu bằng cách tạo kết nối Transmission Control Protocol/Internet Protocol (TCP/IP) tới broker bằng cách sử dụng cổng tiêu chuẩn hoặc cổng tùy chỉnh được xác định bởi các nhà phát triển broker. Khi tạo kết nối, điều quan trọng là phải nhận ra rằng máy chủ có thể tiếp tục một phiên cũ nếu nó được cung cấp ID máy khách mà được sử dụng lại.

Các cổng tiêu chuẩn là 1883 cho giao tiếp không mã hóa và 8883 cho giao tiếp được mã hóa – sử dụng Lớp cổng bảo mật (SSL) / Bảo mật lớp truyền tải (TLS). Trong quá trình giao tiếp SSL/TLS, máy khách cần kiểm chứng và xác thực máy chủ. Máy khách cũng có thể cung cấp tính xác thực máy khách cho broker trong quá trình giao tiếp. Broker có thể sử dụng điều này để xác thực máy khách. Mặc dù không phải là một phần cụ thể của đặc trưng MQTT, nhưng các broker đã trở thành thông lệ để hỗ trợ xác thực máy khách bằng SSL/TLS phía máy khách.

Trong đó:

  • Broker: là một thành phần trung gian (môi giới)
  • SSL/TLS (Secure Sockets Layer/Transport Layer Security) là kỹ thuật mã hóa truyền tin trên internet.

Giao thức MQTT được phát hành nhằm mục đích trở thành một giao thức dành cho các thiết bị IoT và hạn chế tài nguyên tiêu tốn, SSL/TLS không phải là một tùy chọn bắt buộc và trong một số trường hợp nó không cần thiết. Trong những trường hợp như vậy, việc xác thực được thực hiện dưới dạng tên người dùng và mật khẩu, được máy khách gửi đến máy chủ – đây là một phần của gói CONNECT/CONNACK. Ngoài ra, một số broker, đặc biệt là các broker mở được công bố trên internet, sẽ chấp nhận các tài khoản máy khách ẩn danh. Trong những trường hợp như vậy, tên người dùng và mật khẩu chỉ đơn giản là được bỏ trống – không sử dụng tài khoản.

MQTT được gọi là một giao thức nhẹ vì tất cả các thông điệp của nó chỉ có một mã nhỏ. Mỗi thông báo bao gồm một tiêu đề cố định – 2  byte  – một tiêu đề biến tùy chọn, dung lượng thông điệp được giới hạn ở 256 megabyte (MB) và mức chất lượng dịch vụ ( QoS ).

Trong giai đoạn giao tiếp, máy khác có thể thực hiện các thao tác publish, subscribe, unsubscribe và ping. Thao tác publish sẽ gửi một khối dữ liệu nhị phân  – nội dung – đến một chủ đề do nhà xuất bản xác định.

MQTT hỗ trợ các thông điệp đối tượng nhị phân có kích thước lớn lên đến 256 MB. Định dạng của nội dung sẽ dành riêng cho từng ứng dụng. Subscribe được thực hiện bằng cách sử dụng gói SUBSCRIBE/SUBACK và việc unsubscribe được thực hiện tương tự bằng cách sử dụng gói UNSUBSCRIBE/UNSUBACK.

Các chuỗi chủ đề tạo thành một cây chủ đề tự nhiên với việc sử dụng một ký tự phân tách đặc biệt, dấu gạch chéo (/). Máy khách có thể subscribe và unsubscribe – toàn bộ các nhánh trong cây chủ đề bằng cách sử dụng các ký tự thẻ đại diện đặc biệt. Có hai ký tự thẻ đại diện: ký tự thẻ đại diện cấp một, ký tự dấu cộng (+); và một ký tự thẻ đại diện đa cấp, ký tự thăng (#). Một ký tự chủ đề đặc biệt, ký tự đô la ($), loại trừ một chủ đề khỏi bất kỳ subscribe ký tự đại diện gốc nào. Thông thường, $ được sử dụng để vận chuyển các thông điệp hệ thống hoặc máy chủ cụ thể.

Một thao tác khác mà máy khách có thể thực hiện trong giai đoạn giao tiếp là ping broker server bằng cách sử dụng gói PINGREQ/PINGRESP. Thao tác này không có chức năng nào khác ngoài việc duy trì kết nối trực tiếp và đảm bảo kết nối TCP không bị ngắt bởi gateway hoặc router.

Khi một publisher hoặc subscriber muốn kết thúc một phiên MQTT, nó sẽ gửi một thông báo DISCONNECT – HỦY KẾT NỐI đến broker và sau đó ngắt kết nối. Điều này được gọi là graceful shutdown vì nó mang lại cho máy khách khả năng dễ dàng kết nối lại bằng cách cung cấp ID máy khách và tiếp tục lại nơi nó đã dừng.

Nếu việc ngắt kết nối xảy ra đột ngột mà không có thời gian để publisher gửi thông điệp HỦY KẾT NỐI, broker có thể gửi cho subscriber một thông điệp từ publisher mà broker đã lưu vào bộ nhớ cache trước đó. Thông điệp, được gọi là testament, cung cấp cho subscriber hướng dẫn về những việc cần làm nếu publisher ngắt kết nối đột ngột.

MQTT Message Description
CONNECT Client request to connect to server
CONNACK Connect acknowledgement
PUBLISH Publish message
PUBACK Publish acknowledgement
PUBREC Publish received
PUBREL Publish release
PUBCOMP Publish complete
SUBSCRIBE Client subscribe request
SUBACK Subscribe acknowledgement
UNSUBSCRIBE Unsubscribe request
UNSUBACK Unsubscribe acknowledgement
PINGREQ PING request
PINGRESP PING response
DISCONNECT Client is disconnecting

Lịch sử phát triển giao thức MQTT

MQTT được tạo ra vào năm 1999 bởi Tiến sĩ Andy Stanford-Clark của IBM và Arlen Nipper của Arcom (nay là Eurotech). MQTT được tạo ra với mục đích đem lại tính hiệu quả về chi phí và sự đáng tin cậy nhằm kết nối các thiết bị giám sát được sử dụng trong ngành dầu khí với máy chủ giám sát từ xa. Khi gặp thách thức với việc tìm cách đẩy dữ liệu từ các cảm biến đường ống trong sa mạc sang các hệ thống điều khiển, giám sát và thu thập dữ liệu (SCADA) bên ngoài, họ đã quyết định sử dụng cấu trúc liên kết publish/subscribe dựa trên TCP/IP hướng sự kiện để truyền tải dữ liệu và làm giảm chi phí đầu tư xuống.

Mặc dù MQTT vẫn còn mối quan hệ chặt chẽ với IBM, nhưng giờ đây nó là một giao thức mở được quản lý bởi Organization for the Advancement of Structured Information Standards (OASIS).

MQTT không phải là một phần của IBM MQSeries; và kể từ phiên bản 7.1, nó có sẵn trong WebSphere MQ. MQTT trước đây còn được gọi là SCADA protocol, MQ Integrator SCADA Device Protocol (MQIsdp) và WebSphere MQTT (WMQTT). Tuy nhiên, tất cả các biến thể này đã không còn được sử dụng.

MQTT chính thức được phê duyệt là tiêu chuẩn OASIS vào ngày 28 tháng 10 năm 2015. Vào cuối tháng 1 năm 2016, nó đã được chấp nhận là tiêu chuẩn của Tổ chức Tiêu chuẩn hóa Quốc tế (ISO). Giao thức này liên tục được cải thiện và hiện hỗ trợ WebSockets, một giao thức khác cho phép giao tiếp hai chiều giữa máy khách và broker trong thời gian thực.

MQTT trong IoT

MQTT là một trong những giao thức được sử dụng phổ biến nhất liên quan đến IoT. MQTT cho phép các thiết bị IoT hạn chế về tài nguyên gửi hoặc xuất bản thông tin về một chủ đề nhất định tới một máy chủ có chức năng như một message broker MQTT. Sau đó, broker sẽ đẩy thông tin ra ngoài cho những máy khách đã subscribe chủ đề trước đó. Đối với con người, một chủ đề trông giống như một đường dẫn tệp phân cấp. Máy khách có thể subscribe một cấp cụ thể trong hệ thống phân cấp của chủ đề hoặc sử dụng ký tự đại diện để subscribe nhiều cấp.

Ví dụ: các nền tảng IoT của Carriots, Evrything và ThingWorx hỗ trợ giao thức MQTT.

Các giao thức cạnh tranh với MQTT

  1. CoAP – Constrained Application Protocol: sử dụng kiểu giao tiếp request/response (yêu cầu/phản hồi).
  2. AMQP – Advanced Message Queuing Protocol: giống MQTT, sử dụng kiểu giao tiếp publish/subscribe.
  3. SIOMP – Simple/Streaming Text Oriented Messaging Protocol là giao thức dựa trên nền tảng văn bản.
  4. Mosquitto là một mã nguồn mở của MQTT broker.
  5. SMCP – Simple Media Control Protocol là một ngăn xếp CoAP được sử dụng trong môi trường nhúng.
  6. SSI – Simple Sensor Interface: là giao thức truyền thông giúp giao tiếp dữ liệu giữa máy tính và cảm biến.
  7. DDS – Data Distribution Service: có thể publish/ subscribe trực tiếp trong thời gian thực cho các hệ thống nhúng.

Ưu điểm của MQTT

MQTT cho phép hệ thống SCADA của bạn truy cập dữ liệu IIoT. MQTT mang lại nhiều ưu điểm vượt trội cho hệ thống của bạn:

  • Phân phối thông tin hiệu quả hơn
  • Tăng khả năng mở rộng
  • Giảm đáng kể tiêu thụ băng thông mạng
  • Giảm tốc độ cập nhật xuống giây
  • Rất phù hợp cho điều khiển và viễn thám
  • Tối đa hóa băng thông đang sử dụng
  • Chi phí đầu tư cực kỳ thấp
  • Rất an toàn (bảo mật dựa trên sự cấp phép)
  • Đã được sử dụng bởi các ngành công nghiệp dầu khí, Amazon, Facebook và các doanh nghiệp lớn khác
  • Giảm thiểu thời gian phát triển
  • Giao thức publish/subscribe thu thập nhiều dữ liệu hơn với ít băng thông hơn so với giao thức cũ.

Nhược điểm của MQTT

  • MQTT có chu kỳ truyền chậm hơn so với CoAP.
  • Tài nguyên của MQTT hoạt động dựa trên subscribe động, trong khi CoAP sử dụng hệ thống tài nguyên tĩnh – ổn định.
  • MQTT không được mã hóa. Thay vào đó, nó sử dụng TLS / SSL để mã hóa bảo mật.
  • Rất khó để tạo ra một mạng MQTT có thể mở rộng toàn cầu.

Một số ứng dụng MQTT đã được triển khai

  • Facebook Messenger: Facebook đã sử dụng các khía cạnh của MQTT trong Facebook Messenger để trò chuyện trực tuyến . Tuy nhiên, không rõ MQTT được sử dụng bao nhiêu hoặc để làm gì.
  • IECC Scalable: DeltaRail phiên bản mới nhất của hệ thống kiểm soát hiệu IECC của họ đã sử dụng MQTT cho thông tin liên lạc trong các phần khác nhau của hệ thống và các thành phần khác của hệ thống báo hiệu. Nó cung cấp khung truyền thông cơ bản cho một hệ thống tuân thủ các tiêu chuẩn CENELEC cho các thông tin liên lạc quan trọng về an toàn.
  • Amazon Web Services đã công bố Amazon IoT dựa trên MQTT vào năm 2015.
  • Các tổ chức không gian địa lý SensorThings API đặc điểm kỹ thuật tiêu chuẩn có một phần mở rộng MQTT trong tiêu chuẩn như một giao thức thông báo bổ sung ràng buộc. Nó đã được chứng minh trong một thí điểm IoT của Bộ An ninh Nội địa Hoa Kỳ.
  • Các dịch vụ của Cơ sở hạ tầng thượng nguồn OpenStack được kết nối bằng một bus tin nhắn hợp nhất MQTT với Mosquitto là broker MQTT.
  • Adafruit đưa ra một MQTT miễn phí Cloud Service cho thí nghiệm IOT và người học gọi Adafruit IO trong năm 2015.
  • Microsoft Azure IoT Hub sử dụng MQTT làm giao thức chính cho các tin nhắn từ xa .
  • XIM, Inc. đã ra mắt ứng dụng khách MQTT có tên MQTT Buddy vào năm 2017. Đây là ứng dụng MQTT dành cho Android và iOS , nhưng không phải là F-Droid , người dùng có sẵn bằng tiếng Anh, tiếng Nga và tiếng Trung Quốc.
  • Node-RED hỗ trợ các nút MQTT kể từ phiên bản 0.14, để định cấu hình đúng các kết nối TLS.
  • Nền tảng tự động hóa phần mềm nguồn mở Home Assistant được bật MQTT và cung cấp bốn tùy chọn cho các broker MQTT.

Giao tiếp giữa iOS và Raspberry Pi bằng MQTT

Giả sử bạn có đèn LED được kết nối với pin GPIO của Raspberry và bạn muốn bật và tắt. Một cách để giải quyết vấn đề này là sử dụng một nút. Bạn kết nối một nút với một pin GPIO khác. Từ đây, bạn sẽ tạo một chương trình phát hiện các thay đổi trong trạng thái của nút và xác định nên bật hay tắt đèn LED. Điều này sẽ dễ dàng thực hiện được. Tuy nhiên, nếu bạn ở xa nút bấm đó thì sao? Sẽ thật rắc rối khi quay trở lại Raspberry Pi và nhấn nút để bật hoặc tắt đèn LED. Sẽ không hay chút nào nếu bạn có thể bật hoặc tắt đèn LED từ xa từ một thiết bị di động như iPhone hoặc iPad ?

Đối với hướng dẫn này, một thiết bị iOS và Raspberry Pi sẽ là client. Những client này sẽ kết nối với máy chủ MQTT. Câu hỏi là, máy chủ MQTT ở đâu ?

Điều này nghe có vẻ lạ, nhưng Raspberry Pi là máy chủ MQTT. Nói cách khác, Raspberry Pi là máy khách và là máy chủ MQTT cùng một lúc. Nó sẽ giao tiếp với chính nó.

Để rõ ràng hơn, máy chủ MQTT chỉ đơn giản là một chương trình sẽ chạy trong nền trên Raspberry Pi. Máy chủ MQTT sẽ nhận các tin nhắn được gửi bởi các máy khách và gửi chúng đến các máy khách khác được kết nối với máy chủ MQTT. Một client gửi tin nhắn được gọi là một publisher . Một client nhận được tin nhắn được gọi là một thuê bao. Mỗi tin nhắn được gửi bởi một publisher có chứa một threads. Một thuê bao được đăng ký (hoặc đăng ký) vào threads đó sẽ nhận được tin nhắn. Trong ví dụ này, giả sử rằng publisher là thiết bị iOS và subscriberlà Raspberry Pi. Thông báo được tạo bởi publisher có threads “resetGPIO” và Raspberry Pi được đăng ký với threads “resetGPIO”.

Như bạn có thể thấy từ hình ảnh trên cùng, thiết bị iOS là publisher . Nó sẽ gửi một tin nhắn với threads “resetGPIO”. Thông báo này được nhận bởi máy chủ MQTT. Máy chủ MQTT tìm kiếm thuê bao được đăng ký theo threads của tin nhắn. Vì Raspberry Pi được đăng ký vào threads “resetGPIO”, máy chủ MQTT sẽ gửi tin nhắn đến chính Raspberry Pi và tin nhắn được gửi thành công. Bây giờ, điều gì xảy ra nếu publisher gửi tin nhắn có threads mà không có subscribernào được đăng ký?

Thông điệp chỉ đơn giản là bị ném ra ngoài vì không có đích đến cho nó.

Vì chúng ta đang thảo luận về việc gửi tin nhắn từ publisher đến một thuê bao, client có thể là publisher và thuê bao cùng một lúc không? Câu trả lời là có! Giả sử rằng một thiết bị iOS xuất bản đến threads “resetGPIO” và được đăng ký vào threads “sensorData”. Raspberry Pi xuất bản đến threads “sensorData” và được đăng ký vào threads “resetGPIO”.

Từ hình ảnh trên cùng, thiết bị iOS sẽ gửi một tin nhắn với threads “resetGPIO” và được máy chủ MQTT nhận được. Vì bản thân Raspberry Pi đã được đăng ký vào threads “resetGPIO”, máy chủ MQTT sẽ gửi tin nhắn đến chính nó và tin nhắn được gửi thành công. Raspberry Pi gửi một tin nhắn với threads “sensorData” và vì máy chủ MQTT đang chạy trên chính Raspberry Pi, nó sẽ gửi tin nhắn đến chính nó. Vì thiết bị iOS được đăng ký threads “sensorData”, máy chủ MQTT sẽ gửi tin nhắn đến thiết bị iOS và tin nhắn được gửi thành công.

Nghe có vẻ khó hiểu? Nếu vậy, điều đó tốt vì bây giờ chúng ta sẽ xem những gì đang xảy ra đằng sau hậu trường. Điều này sẽ làm sáng tỏ mọi thứ. Trong ví dụ này, chúng tôi có hai client sẽ liên lạc với nhau. Hai client là một thiết bị iOS và Raspberry Pi. Thiết bị iOS sẽ chạy một ứng dụng thực hiện giao thức MQTT trong khi Raspberry Pi sẽ chạy một chương trình thực hiện giao thức MQTT.

Ứng dụng iOS sẽ chứa code thực hiện mô hình publisher và / hoặc người đăng ký. Điều tương tự cũng xảy ra với Raspberry Pi. Chương trình Raspberry Pi thực hiện mô hình publisher và / hoặc thuê bao. Tất cả những gì còn lại là chương trình máy chủ MQTT. Raspberry Pi cũng có thể chạy chương trình máy chủ MQTT vì nó thực sự dễ dàng để khởi động và chạy trên nền tảng Raspberry Pi.

Raspberry Pi hiện đang chạy hai chương trình, máy chủ MQTT và chương trình thực hiện mô hình publisher và / hoặc thuê bao. Để giao thức MQTT hoạt động, mỗi máy khách sẽ tự đăng ký với chương trình máy chủ MQTT. client sẽ cung cấp tên, địa chỉ mạng và các threads được đăng ký, nếu có. Khi publisher (ứng dụng khách gửi tin nhắn) gửi tin nhắn, tin nhắn sẽ đến Raspberry Pi nơi máy chủ MQTT sẽ chặn tin nhắn. Máy chủ MQTT sẽ xác định threads của tin nhắn nhận được và tìm kiếm những người đăng ký đã đăng ký (client đăng ký một threads cụ thể) đã đăng ký threads đó. Nếu chính Raspberry Pi được đăng ký vào threads đó, thì máy chủ MQTT sẽ gửi tin nhắn đến chính Raspberry Pi nhưng bây giờ tin nhắn sẽ được nhận bởi chương trình Raspberry Pi. Điều này giải thích tại sao Raspberry Pi gửi tin nhắn đến chính nó. Đó là để gửi tin nhắn đến chương trình máy chủ MQTT hoặc cho chương trình Raspberry Pi để nhận tin nhắn được gửi bởi máy chủ MQTT.

Điều cuối cùng mà bạn có thể tự hỏi là, chính xác thì một tin nhắn chứa gì? Rất đơn giản, một threads và một thông điệp! Nhưng từ góc độ code hóa, threads và thông điệp chỉ đơn giản là các chuỗi như “1234567890” hoặc “on-off” hoặc “true” hoặc “tv đang bật”.

Trên đây, Chúng tôi đã chia sẻ cho các bạn những kiến thức tổng quan về MQTT bao gồm: định nghĩa, nguyên lý hoạt động, lịch sử phát triển, các giao thức cạnh tranh với MQTT, ưu – nhược điểm và ứng dụng của MQTT. Hy vọng rằng, những kiến thức trên có thể giúp ích cho các bạn đang nghiên cứu, tìm hiểu, học tập hay làm việc với giao thức MQTT. Xin cảm ơn!

Đăng nhận xét