{"id":7194,"date":"2016-07-07T21:00:41","date_gmt":"2016-07-07T19:00:41","guid":{"rendered":"http:\/\/blog.wenzlaff.de\/?p=7194"},"modified":"2023-08-20T14:55:13","modified_gmt":"2023-08-20T12:55:13","slug":"paho-mqtt","status":"publish","type":"post","link":"http:\/\/blog.wenzlaff.de\/?p=7194","title":{"rendered":"Besser als Fussball:  MQTT Java Client mit Paho"},"content":{"rendered":"<p><a href=\"https:\/\/de.wikipedia.org\/wiki\/Fu%C3%9Fball\" target=\"_blank\" rel=\"noopener\">Fussball<\/a>? Wie kann man per Java einen MQTT Client mit <a href=\"https:\/\/eclipse.dev\/paho\/\" target=\"_blank\" rel=\"noopener\">Paho<\/a> schreiben, der z.B. die Anzahl Flugzeuge in Hannover anzeigt? Und das innerhalb der <a href=\"https:\/\/de.wikipedia.org\/wiki\/Halbzeit\" target=\"_blank\" rel=\"noopener\">ersten Halbzeit<\/a>, da nur 2 Klassen ben\u00f6tigt werden.<\/p>\n<p>Mein Raspberry Pi sendet an den \u00f6ffentlichen Testserver <strong>test.mosquitto.org<\/strong> unter den Topic <strong>\/Anzahl\/Flugzeuge\/Hannover<\/strong> alle 5 Minuten die aktuelle Anzahl, so das dieses Beispiel jeder nachvollziehen kann.<\/p>\n<p>Hier die Architektur: <\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/mqtt.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/mqtt-1024x598.png\" alt=\"mqtt\" width=\"640\" height=\"374\" class=\"aligncenter size-large wp-image-7195\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/mqtt-1024x598.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/mqtt-300x175.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/mqtt-768x448.png 768w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Wir brauchen zuerst ein Eclipse Maven Projekt mit Java 1.8 mit dieser <strong>pom.xml<\/strong> und einen Eintrag des Paho Repo, da es in Maven Central nicht vorhanden ist:<!--more--><\/p>\n<pre class=\"lang:xhtml decode:true \" >\r\n&lt;project xmlns=\"http:\/\/maven.apache.org\/POM\/4.0.0\" xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\r\n\txsi:schemaLocation=\"http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd\"&gt;\r\n\t&lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;\r\n\t&lt;groupId&gt;de.wenzlaff.mqtt.client&lt;\/groupId&gt;\r\n\t&lt;artifactId&gt;de.wenzlaff.mqtt.client&lt;\/artifactId&gt;\r\n\t&lt;version&gt;0.0.1-SNAPSHOT&lt;\/version&gt;\r\n\r\n\t&lt;repositories&gt;\r\n\t\t&lt;repository&gt;\r\n\t\t\t&lt;id&gt;Eclipse Paho Repo&lt;\/id&gt;\r\n\t\t\t&lt;url&gt;https:\/\/repo.eclipse.org\/content\/repositories\/paho-releases\/&lt;\/url&gt;\r\n\t\t&lt;\/repository&gt;\r\n\t&lt;\/repositories&gt;\r\n\r\n\t&lt;dependencies&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.eclipse.paho&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;org.eclipse.paho.client.mqttv3&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;1.0.2&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.slf4j&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;slf4j-api&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;1.7.13&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t\t&lt;dependency&gt;\r\n\t\t\t&lt;groupId&gt;org.slf4j&lt;\/groupId&gt;\r\n\t\t\t&lt;artifactId&gt;slf4j-log4j12&lt;\/artifactId&gt;\r\n\t\t\t&lt;version&gt;1.7.13&lt;\/version&gt;\r\n\t\t&lt;\/dependency&gt;\r\n\t&lt;\/dependencies&gt;\r\n\r\n&lt;\/project&gt;<\/pre>\n<p>Dann eine <strong>FlugClient.java<\/strong> Klasse:<\/p>\n<pre class=\"lang:java decode:true \" >\r\npackage de.wenzlaff.mqtt.client;\r\n\r\nimport java.util.UUID;\r\n\r\nimport org.eclipse.paho.client.mqttv3.MqttClient;\r\nimport org.eclipse.paho.client.mqttv3.MqttException;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n\/**\r\n * MQTT Flug Client.\r\n * \r\n * @author Thomas Wenzlaff\r\n *\r\n *\/\r\npublic class FlugClient {\r\n\r\n\tprivate static final Logger LOG = LoggerFactory.getLogger(FlugClient.class);\r\n\r\n\t\/** Die URI des Servers der abgefragt wird. *\/\r\n\tprivate static final String SERVER_URI = \"tcp:\/\/test.mosquitto.org\";\r\n\r\n\t\/** Der Topic auf den die Flugdaten ankommen. *\/\r\n\tprivate static final String FLUG_TOPIC = \"\/Anzahl\/Flugzeuge\/Hannover\";\r\n\r\n\tpublic static void main(String[] args) throws Exception {\r\n\r\n\t\tstartClientEndlos();\r\n\t}\r\n\r\n\tprivate static void startClientEndlos() throws MqttException {\r\n\r\n\t\tLOG.info(\"Starte MQTT Flug Client ...\");\t\t\r\n\r\n\t\tMqttClient client = new MqttClient(SERVER_URI, generateClientId());\r\n\r\n\t\tclient.setCallback(new LogCallback());\r\n\r\n\t\tclient.connect();\r\n\r\n\t\tclient.subscribe(FLUG_TOPIC);\r\n\t}\r\n\r\n\tprivate static String generateClientId() {\r\n\t\treturn UUID.randomUUID().toString();\r\n\t}\r\n}\r\n<\/pre>\n<p>Dann noch eine MQTT Callback Klasse mit Namen <strong>LogCallback.java<\/strong>. Hier ein einfaches Beispiel das nur per Log4j auf der Konsole loggt:<\/p>\n<pre class=\"lang:java decode:true \" >\r\npackage de.wenzlaff.mqtt.client;\r\n\r\nimport org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;\r\nimport org.eclipse.paho.client.mqttv3.MqttCallback;\r\nimport org.eclipse.paho.client.mqttv3.MqttMessage;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n\/**\r\n * Callback Klasse die nur die Nachrichten loggt.\r\n * \r\n * @author Thomas Wenzlaff\r\n *\r\n *\/\r\nclass LogCallback implements MqttCallback {\r\n\r\n\tprivate static final Logger LOG = LoggerFactory.getLogger(LogCallback.class);\r\n\r\n\tpublic void connectionLost(Throwable throwable) {\r\n\t}\r\n\r\n\tpublic void messageArrived(String t, MqttMessage m) throws Exception {\r\n\t\tString nachricht = m.toString().replaceAll(\"#\", \"\");\r\n\r\n\t\tLOG.info(\"{}\", nachricht);\r\n\t}\r\n\r\n\tpublic void deliveryComplete(IMqttDeliveryToken t) {\r\n\t}\r\n\r\n}<\/pre>\n<p>Es kann aber auch leicht erweitert werden, einfach das Interface MqttCallback in einer Callback Klasse implementieren. Die ankommenden Meldungen werden in der <strong>messageArrived<\/strong> Methode behandelt.<\/p>\n<p>Wenn wir nun die <strong>FlugClient<\/strong> Klasse starten, wird auf der Konsole alle 5 Minuten die Anzahl Flugzeuge in Hannover in einem eigenen Thread ausgegeben:<\/p>\n<pre class=\"lang:default decode:true \" >\r\nINFO  FlugClient - Starte MQTT Flug Client ...\r\nINFO  LogCallback - 12 Flugzeuge im Umkreis Flughafen Hannover sichtbar via ADSB am Thu Jul 07 2016 19:57:13 GMT+0200 (CEST) mit Raspberry Pi\r\nINFO  LogCallback - 13 Flugzeuge im Umkreis Flughafen Hannover sichtbar via ADSB am Thu Jul 07 2016 20:02:13 GMT+0200 (CEST) mit Raspberry Pi\r\nINFO  LogCallback - 15 Flugzeuge im Umkreis Flughafen Hannover sichtbar via ADSB am Thu Jul 07 2016 20:07:13 GMT+0200 (CEST) mit Raspberry Pi\r\nINFO  LogCallback - 14 Flugzeuge im Umkreis Flughafen Hannover sichtbar via ADSB am Thu Jul 07 2016 20:12:13 GMT+0200 (CEST) mit Raspberry Pi\r\n...\r\n<\/pre>\n<p>Da ich beim Senden der Anzahl die <strong>retained messages<\/strong> (aufbewahrte Nachrichten) auf true gesetzt habe, kommt gleich beim Start des Client die letzte Meldung.<br \/>\nD.h. das sind Nachrichten mit gesetztem Retain-Flag. Meldet sich ein neuer Teilnehmer am Topic an, erh\u00e4lt er als Erstes die letzte Nachricht, die mit diesem Flag im Topic eingetroffen ist. Das gilt auch bei Abonnements mit Wildcards, die das betreffende Topic enthalten.<\/p>\n<p>Die Flugdaten werden \u00fcbrigens von einem eigenen Raspberry Pi mit node-RED von IBM an den Testserver, Twitter, Debug-Konsole und ThinkSpeak gesendet, hier der Flow:<\/p>\n<p><a href=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50-1024x651.png\" alt=\"node-red-flow\" width=\"640\" height=\"407\" class=\"aligncenter size-large wp-image-7198\" srcset=\"http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50-1024x651.png 1024w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50-300x191.png 300w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50-768x488.png 768w, http:\/\/blog.wenzlaff.de\/wp-content\/uploads\/2016\/07\/Bildschirmfoto-2016-07-07-um-20.02.50.png 1100w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>Wer das mal ausprobiert hat, kann gerne einen <strong>Like<\/strong> oder Kommentar hinterlassen. <\/p>\n<p>Oder doch besser <a href=\"https:\/\/de.wikipedia.org\/wiki\/Fu%C3%9Fball\" target=\"_blank\" rel=\"noopener\">Fu\u00dfball<\/a>?<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Fussball? Wie kann man per Java einen MQTT Client mit Paho schreiben, der z.B. die Anzahl Flugzeuge in Hannover anzeigt? Und das innerhalb der ersten Halbzeit, da nur 2 Klassen ben\u00f6tigt werden. Mein Raspberry Pi sendet an den \u00f6ffentlichen Testserver test.mosquitto.org unter den Topic \/Anzahl\/Flugzeuge\/Hannover alle 5 Minuten die aktuelle Anzahl, so das dieses Beispiel &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/blog.wenzlaff.de\/?p=7194\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eBesser als Fussball:  MQTT Java Client mit Paho\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[220,5,2520,1023],"tags":[1298,2549,116,584,2550,2178,1370,56,2359,2548,2473,2547],"class_list":["post-7194","post","type-post","status-publish","format-standard","hentry","category-anleitung","category-java","category-node-red","category-raspberry-pi","tag-anzahl","tag-broker","tag-client","tag-flug","tag-fussball","tag-java","tag-java-1-8","tag-java-client","tag-mqtt","tag-mqtt-client","tag-node-red","tag-paho"],"_links":{"self":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/7194","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7194"}],"version-history":[{"count":0,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=\/wp\/v2\/posts\/7194\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7194"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7194"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.wenzlaff.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7194"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}