Mqtt – ciekawa technologia

MQTT to protokół zupełnie inny niż HTTP. Przyda nam się gdy chcemy zbudować wiele aplikacji wysyłających sobie nawzajem komunikaty. Podobnie jak zdarzenia (eventy) w językach i frameworkach, MQTT pozwala na wysyłanie zdarzeń i nasłuchiwanie na nie między odległymi aplikacjami.

Musimy na chwilę zapomnieć o HTTP. Zapomnijmy o zapytaniach i odpowiedziach serwera. MQTT działa w zupełnie innej architekturze.

Protokół MQTT służy do komunikacji wiele-do-wielu. Jeśli mamy wiele elementów systemu, które muszą wysyłać informacje o zdarzeniach i komunikować się między sobą – MQTT jest dobrym kandydatem.

Facebook messanger działa przez MQTT. Korzystamy z niego na wielu urządzeniach. Gdy prowadzimy rozmowę na komputerze, możemy płynnie przeskoczyć na komórkę i cała historia rozmowy jest dla nas dostępna.

Broker, klient i tematy – to łatwe

Działanie MQTT jest bardzo łatwe. Podczas wyjaśniania pojęć będziemy od razu korzystać z protokołu.

Broker w MQTT pełni rolę serwera albo centralnego huba lub switcha przesyłającego komunikaty. Najpopularniejszy broker to Mosquitto i jest bajecznie prosty w instalacji.  Po zainstalowaniu uruchamiamy program, który czeka na klienty:

$ ./mosquitto
mosquitto version 1.3.5 (build date 2014-10-27 15:13:47+0000) starting
Using default config.
Opening ipv4 listen socket on port 1883.
Opening ipv6 listen socket on port 1883.

Z brokerem łączą się klienty aby nasłuchiwać lub wysyłać wiadomości. Każda wiadomość musi mieć odpowiedni temat (topic) oraz treść. Nasłuchiwanie zawsze dotyczy konkretnych tematów. Spróbujmy w nowej konsoli uruchomić klienta, który słucha (z pakietu mosquito):

$ mosquitto_sub -h 127.0.0.1 -t "adam/temat1"

Składnia jest prosta do zrozumienia. Poadliśmy adres serwera oraz temat. Póki co nic się nie dzieje. Program w konsoli czeka na wiadomości. Za to nasz wcześniej uruchomiony serwer powiedział:

New connection from 127.0.0.1 on port 1883.
New client connected from 127.0.0.1 as mosqpub/22823-adam. (c1, k60).

Serwer mówi, że ma nowego klienta. Czas na wysłanie wiadomości. W kolejnej konsoli piszemy:

$ mosquitto_pub -h 127.0.0.1 -t "adam/temat1" -m "Zyrafy wchodzą do szafy"

Program od razu się zakończy. Natomiast w konsoli, gdzie mieliśmy uruchomiony mosquito_sub zobaczymy naszą wiadomość. W konsoli serwera zauważymy, że pojawił się kolejny klient.

Tematy wiadomości

Temat wiadomości w MQTT to nie tylko prosty tekst. Tematy możemy dzielić na kolejne poziomy zagnieżdżenia tak, jak katalogi na dysku. Możemy więc mieć temat:

serwer1/core/cpu/temperature

W ten sposób jakiś proces może rozgłaszać temperaturę procesora na serwerze. Słuchając na innym temacie nie otrzymamy wiadomości o temperaturze. Możemy za to nasłuchiwać na wielu tematach oraz używać dopasowań. Przykładowo:

+/core/cpu/temperature

Znak plus dopasowuje się do dowolnej nazwy na jednym poziomie. W ten sposób nasłuchujemy informacji o temperaturze ze wszystkich serwerów. Możemy też słuchać wszystkiego, co pasuje do początku wzorca:

serwer1/core/#

Hasz w nazwie oznacza, że dostaniemy wszystkie komunikaty o temacie z początkiem pasującym do podanego.

MQTT w PHP

Protokół jest dostępny w praktycznie każdej platformie i każdym języku programowania. W naszym ulubionym PHP również. Na sieci znajdziemy sporo bibliotek do obsługi MQTT.

Wybrałem bibliotekę dostępną na GitHubie, która ma łatwy w użyciu interfejs. Po dołączeniu jej do kodu możemy połączyć się z serwerem jako klient MQTT i wysłać wiadomość:

$mqtt = new phpMQTT("127.0.0.1", 1883, "phpMQTT Pub Example");
if ($mqtt->connect()) {
   $mqtt->publish("adam/temat1","Hello World!",0);
   $mqtt->close();
}

Jeśli nasz broker mosquitto nadal działa i nadal nasłuchujemy programem mosquitto_sub, w jego konsoli zobaczymy naszą wiadomość „Hello World!”.

Równie łatwe jest odbieranie wiadomości. Wystarczy zapisać się na subskrypcję tematu. Najpierw stwórzmy funkcję odbierającą wiadomości:

function Message($topic,$msg) {
   printf("Topic: %s; Message: %s\n",$topic,$msg);
}

A następnie podłączmy ją do MQTT i zapiszmy się na temat:

$mqtt = new phpMQTT("127.0.0.1", 1883, "phpMQTT Sub Example");
$mqtt->connect();
$topics['adam/#'] = ["qos"=>0, "function"=>"Message"];
$mqtt->subscribe($topics,0);
 
while($mqtt->proc()){}
$mqtt->close();

Widzimy, że możemy zdefiniować wiele tematów i osobne funkcje dla każdego z nich. Jeśli uruchomimy nasz skrypt w konsoli, będzie czekał na wiadomości i wypisywał wszystko, co otrzyma.

To wszystko, czego potrzebujemy żeby rozmawiać z brokerem MQTT. Jak zwykle, jest to łatwe i przyjemne.

MQTT i JavaScript

Trochę trudniej jest korzystać z MQTT z poziomu JavaScriptu. Musimy skompilować mosquitto z obsługą WebSocket. Gdy już to zrobimy, mamy do dyspozycji np. bibliotekę Paho, która pozwała w łatwy sposób korzystać z protokołu. Znów stworzymy sobie funkcję odbierającą komunikaty:

function onMessage(message) {
   console.log("Message:"+message.payloadString);
}

Następnie tworzymy połączenie:

client = new Paho.MQTT.Client("127.0.0.1", port, "Nazwa Klienta");
client.onMessageArrived = onMessage;

A gdy połączenie zostanie nawiązane, nasłuchujemy:

client.connect({onSuccess:onConnect});
function onConnect() {
   console.log("onConnect");
   client.subscribe("adam/#");
}

Możemy też wysyłać wiadomości:

message = new Paho.MQTT.Message("Hello");
message.destinationName = "adam/example";
client.send(message);

Na koniec

Protokół MQTT może nam się przydać gdy mamy wiele elementów systemu. Te elementy muszą komunikować się ze sobą w elastyczny sposób. Np. lokalna sieć urządzeń na pokładzie samochodu, autobusu, pociągu, statku lub urządzenia w ramach inteligentnego domu. Możemy bez problemu przesyłać wiadomości w JSON lub XML.

Warto poczytać oficjalną dokumentację MQTT oraz zajrzeć na stronę Mosquitto.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *