Cloudmqtt là gì

tôi đang suy nghĩ về cách điều khiển hệ thống khí canh của mình từ xa thông qua internet. raspberry pi điều khiển hệ thống được kết nối với internet thông qua bộ định tuyến. tôi có thể truy cập pi raspberry bằng cách chuyển tiếp cổng và những thứ tương tự nhưng nó phức tạp. tùy chọn tiếp theo của tôi có thể là sử dụng websockets nhưng tôi cảm thấy nó quá mức cần thiết cho các ứng dụng chạy trong pi.

Gần đây tôi nhận được một refcard từ DZone liên quan đến một giao thức gọi là mqtt. tôi đã không biết về giao thức này trước đây. vì vậy tôi đã nghĩ đến việc thực hiện một số thử nghiệm với nó. Tôi không đi sâu hơn vào giao thức, thẻ tham chiếu dzone đã làm rất tốt việc giải thích nó tốt.

Tóm lại, mqtt bao gồm ba phần.

  • người môi giới
  • người đăng ký
  • nhà xuất bản

nhà xuất bản phát hành một thông điệp cho một chủ đề cụ thể và bất kỳ người đăng ký nào đã đăng ký chủ đề đó sẽ nhận được thông điệp. nhà môi giới là đầu mối trung tâm. cả nhà xuất bản và người đăng ký đều được kết nối với nhà môi giới và nó sẽ đảm nhận việc truyền tải thông điệp đến tất cả những người đăng ký đã đăng ký chủ đề.

người môi giới

chúng tôi có thể triển khai nhà môi giới của riêng mình bằng cách sử dụng rabitmq hoặc một plugin mosca cho node.js hoặc bất kỳ nhà môi giới mqtt nào khác có sẵn trên thị trường. để thử nghiệm với nó, tôi đã sử dụng addon cloudmqtt trong heroku . tôi đã sử dụng heroku chỉ để quản lý mọi thứ từ một nơi trung tâm.

môi trường dev

tôi đã tạo hai bộ ứng dụng node.js, một bộ chạy trong máy tính của tôi với tư cách là nhà xuất bản và bộ khác chạy trong raspberrypi của tôi với tư cách là người đăng ký. cả hai đều không có kết nối trực tiếp; thay vào đó họ đã được kết nối với nhà môi giới cloudmqtt. dưới đây là một số mã thử nghiệm.

mã nhà xuất bản

var mqtt = require['mqtt']; var client = mqtt.createclient['', 'm11.cloudmqtt.com', { username: '', password: '' }]; client.on['connect', function [] { // when connected // subscribe to a topic client.subscribe['temperature_reading', function [] { // when a message arrives, do something with it client.on['message', function [topic, message, packet] { console.log["received '" + message + "' on '" + topic + "'"]; }]; }]; // publish a message to a topic client.publish['set_temperature', '24', function [] { console.log["message is published"]; }]; }];

mã trên hoạt động như một nhà xuất bản cũng như một người đăng ký. Ví dụ: đoạn mã trên có thể là một đoạn mã chạy trên internet và số pi có thể xuất bản các kết quả đọc nhiệt độ trong một khoảng thời gian định kỳ và ghi nó vào cơ sở dữ liệu trung tâm. chúng tôi có thể xem các bài đọc qua ứng dụng web hoặc bất kỳ cách nào chúng tôi cần. Ngoài ra, nếu được yêu cầu, chúng tôi có thể đặt nhiệt độ cho tất cả các pis mâm xôi được kết nối bằng cách xuất bản một thông báo tới chủ đề 'set_tempeosystem'.

mã thuê bao

var mqtt = require['mqtt'], url = require['url']; var client = mqtt.createclient['', 'm11.cloudmqtt.com', { username: '', password: '' }]; client.on['connect', function [] { // when connected // subscribe to a topic client.subscribe['set_temperature', function [] { // when a message arrives, do something with it client.on['message', function [topic, message, packet] { console.log["received '" + message + "' on '" + topic + "'"]; // set the temperature. }]; }]; }];

mã rất tối thiểu và chúng tôi có thể đạt được giao tiếp dễ dàng với tất cả các thiết bị được kết nối. trong trường hợp trên, các máy khách luôn được kết nối. nếu bạn muốn kết thúc kết nối thì hãy gọi 'client.end []'.

sau đó, tôi đã triển khai một nhà môi giới bằng cách sử dụng mosca, và trong cả hai trường hợp, hệ thống hoạt động thực sự tốt.

MQTT là gì ? Cách sử dụng MQTT như thế nào ? Các ví dụ về MQTT với ESP8266 được thực hiện ra sao ? Trong bài viết này mình sẽ trình bày một số khái niệm và các bước thực hiện MQTT với ví dụ minh họa cơ bản trên ESP8266 cho mọi người cùng tham khảo.

Trước khi bắt đầu mình cùng xem qua một hình ảnh cơ bản về MQTT

Với hình ảnh trên thì ta có thể thấy MQTT Broker là một trạm trung chuyển, nói đơn giản dễ hiểu thì coi như nó là một trung tâm thông tin, có nhiệm vụ nhận thông tin từ rất nhiều các thiết bị khác nhau và chuyển các thông tin này tới từng thiết bị riêng biệt.

Sẽ có một câu hỏi được đặt ra là Broker MQTT này sẽ lấy ở đâu ra ? Chúng ta sẽ có 2 cách

  • Tự tạo Broker MQTT trên máy tính, raspberry, server,.. tùy vào điều kiện hiện có: cách này tốn kém thêm chi phí, phức tạp, không dành cho người mới bắt đầu.
  • Sử dụng các dịch vụ MQTT broker có sẵn: cách này dễ thở hơn chút, sử dụng cái sẵn có, thao tác cấu hình lấy thông tin để sử dụng, phù hợp với những người muốn thử nghiệm, tham khảo, tận dụng cái có sẵn. Trong bài viết này mình sẽ sử dụng cách này.

Để hiểu hơn một chút về cách thức hoạt động của MQTT Broker và ESP8266 ta sẽ đi vào ví dụ cụ thể

Phần cứng

Phần mềm

  • Arduino IDE
  • Thư viện Pubsubclient
  • MQTTlens cho Chrome

Sau khi chuẩn bị đầy đủ đồ nghề thì mình bắt tay vào thử chút thôi. Về cách làm mình sẽ dùng ESP8266 [NodeMCU] làm Client để kết nối lên một dịch vụ MQTT Broker là CloudMQTT với 2 nhiệm vụ chính, nhiệm vụ 1 là tham khảo từ Phan Tiến Sang, nhiệm vụ 2 là thay đổi 1 chút để điều khiển LED

  • Nhiệm vụ 1: Gửi [publish] dữ liệu lên broker, và nhận thông tin [subcribe] từ broker, mục đích chính là kiểm tra publish và subcribe giữa ESP8266 và MQTT Broker.
  • Nhiệm vụ 2: Nhận[subcribe] thông tin từ broker, kiểm tra dữ liệu và thực hiện bật tắt LED

Bước 1: Bạn vào trực tiếp trang CloudMQTT để tạo một tài khoản cho mình, sẽ có một đường dẫn để kích hoạt thông tin và cấu hình cho tài khoản của bạn, trừ email và mật khẩu ra thì các ô còn lại các bạn nhập gì tùy thích.

Bước 2: Tạo MQTT Broker bằng cách ấn vào nút Create màu xanh, nhập các thông tin vào như hình.

Bước 3: Chọn Details để cấu hình thông tin

Trong manage User điền tên user là esp8266, password là 123456, sau đó Save

Trong New Rule chọn user như hình, tên topic đặt demo, tick chọn Read,Write

Vậy là xong bước cấu hình broker, kết quả, ta sẽ quan tâm tới 3 ô khoanh đỏ

Để ESP8266 có thể publish và subcribe dữ liệu lên MQTT broker thì cần phải có thư viện MQTT, ở đây mình dùng thư viện sẵn có là PubSubClient để thử nghiệm cho nhanhChương trình

Mình giải thích qua một chút về chương trình, chương trình này sẽ thực hiện kết nối với mạng wifi trước để có kết nối tới internet, sau đó thực hiện gửi thông tin lên broker bằng lệnh publish, sau đó lắng nghe thông tin có trên Broker[ở đây là thông tin do chính nó gửi lên] và in thông tin này ra terminal của Arduino thông qua hàm callback.

Log Arduino

Log Websocket UI

Coi như đã giao tiếp thực hiện publish và subcribe trên MQTT Broker. Giờ thực hiện cải tiến thêm một chút, là từ giao diện Websocket  UI Send message xuống, ở dưới khi nhận được message thì ESP8266 thực hiện bật/tắt LED có sẵn trên kit.Chương trình

Với chương trình này mình sẽ thay đổi và thực hiện kiểm tra gói tin từ Broker gửi về để điều khiển LED trong hàm callback

Một số ví dụ trên có thể cho chúng ta phần nào hình dung được về MQTT, tất nhiên nó vẫn dừng lại ở mức độ cơ bản. Nói lại cách giao tiếp thông thường khi một device kết nối với server, sẽ gửi POST request với giá trị của sensor[ở đây ví dụ ta sẽ gửi dữ liệu từ sensor lên server], sau đó sẽ là ngắt kết nối với server, đợi khoảng 1 thời gian nào đó, sau đó lặp lại các bước trên. Vậy mỗi lần cần gửi giá trị của sensor thì device lại phải thực hiện kết nối với server lại, việc kết nối nhiều lần ở đây ta thấy là không cần thiết. Ngược lại, nếu chúng ta muốn gửi data từ server về device, thì chỉ có cách duy nhất là device phải kết nối với server và phải thực hiện kiểm tra nếu có update dữ liệu mới. Đây rõ ràng không phải là cách hiệu quả nhất để gửi dữ liệu. Giao thức HTTP sẽ sử dụng phương thức giao tiếp là request-response, phương thức này thì tốt cho việc transfer các dữ liệu lớn nhưng nó không phải là protocol hữu hiệu nhất khi chúng ta chỉ cần gửi vài byte dữ liệu[giá trị sensor], và đó là lý do cần phải dùng MQTT

MQTT [Message Queuing Telemetry Transport] là một giao thức gởi dạng publish/subscribe sử dụng cho các thiết bị Internet of Things với băng thông thấp, độ tin cậy cao và khả năng được sử dụng trong mạng lưới không ổn định. Bởi vì giao thức này sử dụng băng thông thấp trong môi trường có độ trễ cao nên nó là một giao thức lý tưởng cho các ứng dụng M2M. MQTT cũng là giao thức sử dụng trong Facebook Messager.

Các định nghĩa “subscribe”, “publish”, “qos”, “retain”, “last will and testament [lwt]” trong giao thức MQTT là gì ?

Trong một hệ thống sử dụng giao thức MQTT, nhiều node trạm [gọi là mqtt client – gọi tắt là client] kết nối tới một MQTT server [gọi là broker]. Mỗi client sẽ đăng ký một vài kênh [topic], ví dụ như “/client1/channel1”, “/client1/channel2”. Quá trình đăng ký này gọi là “subscribe”, giống như chúng ta đăng ký nhận tin trên một kênh Youtube vậy. Mỗi client sẽ nhận được dữ liệu khi bất kỳ trạm nào khác gởi dữ liệu và kênh đã đăng ký. Khi một client gởi dữ liệu tới kênh đó, gọi là “publish”.

Ở đây có 3 tuỳ chọn *QoS [Qualities of service] * khi “publish” và “subscribe”:

  • QoS0 Broker/client sẽ gởi dữ liệu đúng 1 lần, quá trình gởi được xác nhận bởi chỉ giao thức TCP/IP, giống kiểu đem con bỏ chợ.
  • QoS1 Broker/client sẽ gởi dữ liệu với ít nhất 1 lần xác nhận từ đầu kia, nghĩa là có thể có nhiều hơn 1 lần xác nhận đã nhận được dữ liệu.
  • QoS2 Broker/client đảm bảm khi gởi dữ liệu thì phía nhận chỉ nhận được đúng 1 lần, quá trình này phải trải qua 4 bước bắt tay.

Bạn có thể tham khảo thêm về QoS

Một gói tin có thể được gởi ở bất kỳ QoS nào, và các client cũng có thể subscribe với bất kỳ yêu cầu QoS nào. Có nghĩa là client sẽ lựa chọn QoS tối đa mà nó có để nhận tin. Ví dụ, nếu 1 gói dữ liệu được publish với QoS2, và client subscribe với QoS0, thì gói dữ liệu được nhận về client này sẽ được broker gởi với QoS0, và 1 client khác đăng ký cùng kênh này với QoS 2, thì nó sẽ được Broker gởi dữ liệu với QoS2.

Một ví dụ khác, nếu 1 client subscribe với QoS2 và gói dữ liệu gởi vào kênh đó publish với QoS0 thì client đó sẽ được Broker gởi dữ liệu với QoS0. QoS càng cao thì càng đáng tin cậy, đồng thời độ trễ và băng thông đòi hỏi cũng cao hơn.

Nếu RETAIN được set bằng 1, khi gói tin được publish từ Client, Broker PHẢI lưu trữ lại gói tin với QoS, và nó sẽ được gởi đến bất kỳ Client nào subscribe cùng kênh trong tương lai. Khi một Client kết nối tới Broker và subscribe, nó sẽ nhận được gói tin cuối cùng có RETAIN = 1 với bất kỳ topic nào mà nó đăng ký trùng. Tuy nhiên, nếu Broker nhận được gói tin mà có QoS = 0 và RETAIN = 1, nó sẽ huỷ tất cả các gói tin có RETAIN = 1 trước đó. Và phải lưu gói tin này lại, nhưng hoàn toàn có thể huỷ bất kỳ lúc nào.

Khi publish một gói dữ liệu đến Client, Broker phải se RETAIN = 1 nếu gói được gởi như là kết quả của việc subscribe mới của Client [giống như tin nhắn ACK báo subscribe thành công]. RETAIN phải bằng 0 nếu không quan tâm tới kết quả của viẹc subscribe.

Gói tin LWT [last will and testament] không thực sự biết được Client có trực tuyến hay không, cái này do gói tin KeepAlive đảm nhận. Tuy nhiên gói tin LWT như là thông tin điều gì sẽ xảy đến sau khi thiết bị ngoại tuyến.

MQTT rất nhẹ và nhanh, chỉ cần vài byte để kết nối tới server và kết nối này được giữ mọi lúc. Kết nối của nó sẽ dùng ít dữ liệu và thời gian hơn giao thức HTTP. Vậy MQTT hoạt động ra sao ?

Toàn bộ hệ thống của chúng ta sẽ bao gồm rất nhiều clients và 1 broker duy nhất, tất cả các device của chúng ta được gọi chung là clients, client cũng có thể là điện thoại, là laptop, là pc hoặc là esp8266. Mỗi device này chỉ kết nối với một broker duy nhất và chúng không kết nối với nhau.

Toàn bộ hệ thống sẽ dựa trên phương thức kết nối là publish – subcribe, mỗi client có thể là một publisher – gửi messages, hoặc là subcriber – lắng nghe message tới, hoặc đồng thời là cả 2 trong cùng 1 thời điểm.

Broker ở đây là loại server với nhiệm vụ là cho phép publish mesage từ publisher và chuyển tiếp nó tới subcriber.

Vậy làm thế nào để broker hiểu được để chuyển đúng message tới subscriber ? Chúng ta thử nghĩ nếu mỗi subscriber đều nhận được mọi message, trong khi đó có rất nhiều publisher gửi message trong hệ thống, nghĩa là subscriber sẽ nhận được 1 đống tin nhắn rác, để giải quyết vấn đề này thì cần có các topic.

Mỗi publisher sẽ gửi tới một hoặc nhiều topic và mỗi subscriber sẽ subscribe từ một hoặc nhiều topic có liên quan. Các topic này sẽ có dạng cấu trúc cây, và được phân chia bởi dấu /

Ví dụ 1: Chúng ta có nhiệt độ môi trường ở một số nơi khác nhau và tôi thì thích nhiệt độ ở trong vườn nhà mình. Tôi sẽ dùng smartphone để subscribe topic là Sensors/Garden/Temperature. Còn device dùng để đo nhiệt độ môi trường là ESP8266 sẽ được đặt ở trong vườn, kết nối với internet và publish giá trị nhiệt độ lên topic Sensors/Garden/Temperature, và lúc này thì smartphone của tôi sẽ nhận được thông tin giá trị nhiệt độ hiện tại.

Ví dụ 2: Một ví dụ khác khi bạn dùng với LWT và keep alive là ta có 1 cảm biến, nó gửi những dữ liệu quan trọng và rất không thường xuyên. Nó có publish trước với Broker một tin nhắn lwt ở topic /node/gone-offline với tin nhắn id của nó. Và tôi cũng subscribe topic /node/gone-offline, sẽ gởi SMS tới điện thoại thôi mỗi khi nhận được tin nhắn nào ở kênh mà tôi subscribe.Trong quá trình hoạt động, cảm biến luôn giữ kết nối với Broker bởi việc luôn gởi gói tin keepAlive. Nhưng nếu vì lý do gì đó, cảm biến này chuyển sang ngoại tuyến, kết nối tới Broker timeout do Broker không còn nhận được gói keepAlive.

Lúc này, do cảm biến của tôi đã đăng ký LWT, do vậy broker sẽ đóng kết nối của Cảm biến, đồng thời sẽ publish một gói tin là Id của cảm biến vào kênh /node/gone-offline, dĩ nhiên là tôi cũng sẽ nhận được tin nhắn báo rằng cảm biến yêu quý của mình đã ngoại tuyến.

Video liên quan

Chủ Đề