MQ Telemetry Transport (MQTT) protokol umožňuje přenos informací, zejména od nejrůznějších senzorů a jednoduchých zařízení, do infrastruktury sloužící pro jejich zpracování. S tím souvisí i zobrazení těchto informací koncovým uživatelům na jednoduchých internetových portálech. Pro tento účel je vhodné přetransformovat MQTT do lépe použitelného a infrastrukturou prostupného protokolu, kterým může být websockets. V následujícím textu bude popsáno nastavení a zprovoznění MQTT brokera Mosquitto s reverzním proxy serverem NGINX.
Základní popis protokolu MQTT je možné nalézt v článku „Využití protokolu MQTT nejen pro IoT“.
Nastavení brokera Mosquitto
Broker Mosquitto pracuje zejména s protokolem MQTT. Pokud chceme využít možnosti spolupráce internetových aplikací s touto aplikací, můžeme využít přímo tento protokol, nebo, na základě HTTP postavené, technologie websockets. Nespornou výhodou druhého řešení je nativní podpora ve webových serverech a moderních internetových prohlížečích.
Ve většině distribucí GNU/Linux je dodáván Mosquitto broker bez podpory websockets. Proto bude pravděpodobně nutné překompilovat tuto aplikaci s příslušnou podporou. O procesu rekompilace je možné pro jednotlivé distribuce nalézt potřebné informace na internetu.
Podpora websockets pro Mosquitto se před vlastním překladem ze zdrojových kódů zapíná v souboru config.mk
na rádku WITH_WEBSOCKETS
.
Následné povolení se provádí v souboru mosquitto.conf
, přidáním řádků:
1 2 |
listener 9001 protocol websockets |
Pokud je Mosquitto broker zkompilován s podporou websockets, bude po následném restartu služby otevřen TCP port 9001. V opačném případě nedojde ke spuštění služby, o čemž jsme informováni operačním systémem. Těchto portů, kromě výchozího 1883 určeného pro MQTT, můžeme definovat i více.
TCP porty, na kterých aplikace čeká na příchozí spojení, můžeme vypsat příkazem netstat
:
1 2 3 4 |
[user@linux ~]# netstat -ltpn | grep mosquitto tcp 0 0 0.0.0.0:9001 0.0.0.0:* LISTEN 304/mosquitto tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 304/mosquitto tcp6 0 0 :::1883 :::* LISTEN 304/mosquitto |
Více o nastavení brokera lze nalézt v dokumentaci projektu.
Nastavení reverzní proxy NGINX
Protokol websockets můžeme s Mostquitto brokerem využívat přímo, nicméně pro mnoho aplikací raději použijeme webový server NGINX. Díky tomuto řešení můžeme kombinovat websockets s poskytování statického i dynamického obsahu. Popis nastavení NGINX je součástí článku Síťová infrastruktura pro domácí prostředí a malé firmy (SOHO) – síťové služby 2.
V zásadě máme dvě možnosti. Tou první je zřízení speciální domény pro práci s obsahem pro websockets, nebo využití stávající, již poskytující nějaký webový projekt.
Nová doména pro websockets
Pokud budeme zřizovat novou doménu pro poskytování obsahu websockets, musíme nejdříve provést na našem DNS serveru příslušné operace. Naše příkladová doména se bude jmenovat websockets.my-own-domain.net
.
Do konfiguračního souboru nginx.conf
, části http { … }
, přidáme definici našich serverů s instalovaným brokerem Mosquitto:
1 2 3 4 5 |
upstream socket_nodes { ip_hash; server localhost:9001; server mqtt2.my-own-domain.net:9001; } |
V našem případě máme dva servery poskytující MQTT. Na prvním nám běží webový server NGINX, druhý mqtt2.my-own-domain.net, je další server. Serverů může být samozřejmě i více, nebo pouze jeden.
Nyní přidáme do stejné části (http { … }
) nastavení naší nové domény:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
server { listen 80; server_name websockets.my-own-domain.net; location / { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_pass http://socket_nodes; } } |
Tímto způsobem jsme vytvořili nový virtuální server websockets.my-own-domain.net, naslouchající na portu 80/tcp.
Stávající doména využitá pro websockets
V případě, že chceme využít websockets na stávající doméně, např. my-own-domain.net
, přidáme opět do konfiguračního souboru nginx.conf
, části http { … }
, definici našich serverů s instalovaným brokerem Mosquitto:
1 2 3 4 5 |
upstream socket_nodes { ip_hash; server localhost:9001; server mqtt2.my-own-domain.net:9001; } |
Nyní se přesuneme do části server { … }
konfigurace virtuálního serveru my-own-domain.net
a přidáme definici nového umístění:
1 2 3 4 5 6 7 8 |
location /mqtt { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_pass http://socket_nodes; } |
Důležitý je název cesty /mqtt
. Knihovny MQTT komunikující přes websockets budou totiž většinou ve výchozím stavu hledat právě URL my-own-domain.net/mqtt
.
Problémy s proxy servery
Osobně jsem narazil na problém, kdy komunikace protokolem websockets skrze běžné proxy servery (konkrétně Squid) neprochází. V takovém případě můžeme websockets provozovat skrze protokol HTTPS (port 443/tcp). Toto nastavení se samozřejmě týká pouze našeho web serveru NGINX, kde musíme nastavit patřičný SSL certifikát.
Příkladová aplikace
Příkladová aplikace je dostupná na URL http://app.brichacek.net/examples/websockets/mqtt (zrušeno). Ukazuje příjem informací o počasí ze dvou lokalit. Data jsou sbírána aplikací Collectd, přenášena protokolem MQTT na Mosquitto brokera a následně přes reverzní proxy NGINX, protokol websockets, až do cílové aplikace.
(příkladová webová aplikace vychází z http://jpmens.net/2014/07/03/the-mosquitto-mqtt-broker-gets-websockets-support)