Playing around with MQTT and Java with Moquette and Eclipse Paho

June 1st, 2016 by

The MQ Telemetry Transport Protocol (MQTT) is a lightweight publish/subscribe messaging protocol developed in 1999 that experiences a growing popularity due to trends like the Internet-of-Things and the need to exchange information between low powered devices with aspects as CPU and bandwidth usage in mind.

In the following tutorial I’d like to demonstrate how to set-up a broker for this protocol with the help of the Moquette library and how to create a client and publish messages for a specific topic using this broker and Eclipse Paho as client library.

MQTT Sample Application

MQTT Sample Application

 

Dependencies

We need to add two repositories and the two dependencies for Eclipse Paho and Moquette to our project’s pom.xml:

<repositories>
	<repository>
		<id>bintray</id>
		<url>http://dl.bintray.com/andsel/maven/</url>
		<releases>
			<enabled>true</enabled>
		</releases>
		<snapshots>
			<enabled>false</enabled>
		</snapshots>
	</repository>
	<repository>
		<id>Eclipse Paho Repo</id>
		<url>https://repo.eclipse.org/content/repositories/paho-releases/</url>
	</repository>
</repositories>
<dependencies>
	<dependency>
		<groupId>io.moquette</groupId>
		<artifactId>moquette-broker</artifactId>
		<version>0.8</version>
	</dependency>
	<dependency>
		<groupId>org.eclipse.paho</groupId>
		<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
		<version>1.0.2</version>
	</dependency>
</dependencies>

MQTT in Action

In our sample application we’re creating an MQTT broker first and we’re initializing and using an MQTT client to publish a message afterwards.

MQTT Broker using Moquette

We’re using Moquette as a lightweight, MQTT compliant broker supporting QoS 0-2 here.

The following configuration file named moquette.conf specifies port, host and security properties for the broker:

port 1883
host 0.0.0.0
allow_anonymous true

To intercept and print out incoming messages, we’re adding the following listener class, implementing io.moquette.interception.AbstractInterceptHandler.

class PublisherListener extends AbstractInterceptHandler {
	@Override
	public void onPublish(InterceptPublishMessage message) {
		System.out.println("moquette mqtt broker message intercepted, topic: " + message.getTopicName()
				+ ", content: " + new String(message.getPayload().array()));
	}
}

Now we just need to instantiate the configuration, start the broker, add the interceptor-handler and register a shutdown-hook:

final IConfig classPathConfig = new ClasspathConfig();
 
final Server mqttBroker = new Server();
final List<? extends InterceptHandler> userHandlers = Arrays.asList(new PublisherListener());
mqttBroker.startServer(classPathConfig, userHandlers);
 
System.out.println("moquette mqtt broker started, press ctrl-c to shutdown..");
Runtime.getRuntime().addShutdownHook(new Thread() {
	@Override
	public void run() {
		System.out.println("stopping moquette mqtt broker..");
		mqttBroker.stopServer();
		System.out.println("moquette mqtt broker stopped");
	}
});

MQTT Client using Eclipse Paho

Setting up a client and sending a message is done within a few steps – having created a client instance with specific connection-options, we’re publishing a message to out broker and for the topic named news:

String topic = "news";
String content = "Visit www.hascode.com! :D";
int qos = 2;
String broker = "tcp://0.0.0.0:1883";
String clientId = "paho-java-client";
 
try {
	MqttClient sampleClient = new MqttClient(broker, clientId, new MemoryPersistence());
	MqttConnectOptions connOpts = new MqttConnectOptions();
	connOpts.setCleanSession(true);
	System.out.println("paho-client connecting to broker: " + broker);
	sampleClient.connect(connOpts);
	System.out.println("paho-client connected to broker");
	System.out.println("paho-client publishing message: " + content);
	MqttMessage message = new MqttMessage(content.getBytes());
	message.setQos(qos);
	sampleClient.publish(topic, message);
	System.out.println("paho-client message published");
	sampleClient.disconnect();
	System.out.println("paho-client disconnected");
} catch (MqttException me) {
	me.printStackTrace();
}

Final Application

Putting everything together, this is our simple example application running broker and client when executed:

package com.hascode.tutorial.mqtt;
 
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
 
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
 
import io.moquette.interception.AbstractInterceptHandler;
import io.moquette.interception.InterceptHandler;
import io.moquette.interception.messages.InterceptPublishMessage;
import io.moquette.server.Server;
import io.moquette.server.config.ClasspathConfig;
import io.moquette.server.config.IConfig;
 
public class Main {
 
	static class PublisherListener extends AbstractInterceptHandler {
		@Override
		public void onPublish(InterceptPublishMessage message) {
			System.out.println("moquette mqtt broker message intercepted, topic: " + message.getTopicName()
					+ ", content: " + new String(message.getPayload().array()));
		}
	}
 
	public static void main(String[] args) throws InterruptedException, IOException {
		// Creating a MQTT Broker using Moquette
		final IConfig classPathConfig = new ClasspathConfig();
 
		final Server mqttBroker = new Server();
		final List<? extends InterceptHandler> userHandlers = Arrays.asList(new PublisherListener());
		mqttBroker.startServer(classPathConfig, userHandlers);
 
		System.out.println("moquette mqtt broker started, press ctrl-c to shutdown..");
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				System.out.println("stopping moquette mqtt broker..");
				mqttBroker.stopServer();
				System.out.println("moquette mqtt broker stopped");
			}
		});
 
		Thread.sleep(4000);
 
		// Creating a MQTT Client using Eclipse Paho
		String topic = "news";
		String content = "Visit www.hascode.com! :D";
		int qos = 2;
		String broker = "tcp://0.0.0.0:1883";
		String clientId = "paho-java-client";
 
		try {
			MqttClient sampleClient = new MqttClient(broker, clientId, new MemoryPersistence());
			MqttConnectOptions connOpts = new MqttConnectOptions();
			connOpts.setCleanSession(true);
			System.out.println("paho-client connecting to broker: " + broker);
			sampleClient.connect(connOpts);
			System.out.println("paho-client connected to broker");
			System.out.println("paho-client publishing message: " + content);
			MqttMessage message = new MqttMessage(content.getBytes());
			message.setQos(qos);
			sampleClient.publish(topic, message);
			System.out.println("paho-client message published");
			sampleClient.disconnect();
			System.out.println("paho-client disconnected");
		} catch (MqttException me) {
			me.printStackTrace();
		}
	}
}

Running the Sample Application

We’re now ready to run our application using our IDE of choice or using command line and Maven:

$ mvn compile exec:java -Dexec.mainClass=com.hascode.tutorial.mqtt.Main
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mqtt-java-tutorial 1.0.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.3.1:java (default-cli) @ mqtt-java-tutorial ---
moquette mqtt broker started, press ctrl-c to shutdown..
paho-client connecting to broker: tcp://0.0.0.0:1883
paho-client connected to broker
paho-client publishing message: Visit www.hascode.com! :D
moquette mqtt broker message intercepted, topic: news, content: Visit www.hascode.com! :D
paho-client message published
paho-client disconnected
^Cstopping moquette mqtt broker..
moquette mqtt broker stopped

Tutorial Sources

Please feel free to download the tutorial sources from my Bitbucket repository, fork it there or clone it using Git:

git clone https://bitbucket.org/hascode/mqtt-java-tutorial.git

Resources

Article Updates

  • 2019-05-11: Maven compile step added to build example.

    Tags: , , , , , , , , , ,

    9 Responses to “Playing around with MQTT and Java with Moquette and Eclipse Paho”

    1. Hien Pham Says:

      Hi,
      Thank you for your tutorial, it is really useful for me.
      However, I am struggling with making moquette broker to response to subscribe message from a subscriber. Could you help me figuring out? Thanks

    2. Soo Myo Myint Says:

      Hello,
      Thank you for the code.
      But I have a problem with changing host rather than 0.0.0.0.
      I changed in configuration file and I got
      “java.net.BindException: Cannot assign requested address: bind”.

      I would like to know 0.0.0.o is default value and cannot be changed or
      is there any other way to change?

    3. Micha Kops Says:

      Might it be that the port is already in use?

    4. hosjiu Says:

      Good job

    5. Micha Kops Says:

      Thanks! You’re welcome!

    6. Hemin Says:

      Hello i got below error in ubuntu 16.04. Please advice me if someone have solution.

      [WARNING]
      java.lang.ClassNotFoundException: com.hascode.tutorial.mqtt.Main
      at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
      at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:270)
      at java.lang.Thread.run(Thread.java:748)
      [INFO] ————————————————————————
      [INFO] BUILD FAILURE
      [INFO] ————————————————————————
      [INFO] Total time: 02:26 min
      [INFO] Finished at: 2019-05-08T16:55:10+00:00
      [INFO] Final Memory: 15M/194M
      [INFO] ————————————————————————
      [ERROR] Failed to execute goal org.codehaus.mojo:exec-maven-plugin:1.6.0:java (default-cli) on project mqtt-java-tutorial: An exception occured while executing the Java class. com.hascode.tutorial.mqtt.Main -> [Help 1]
      [ERROR]
      [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
      [ERROR] Re-run Maven using the -X switch to enable full debug logging.
      [ERROR]
      [ERROR] For more information about the errors and possible solutions, please read the following articles:
      [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

      Thanks in advance…!

    7. Micha Kops Says:

      Hi,

      you need to compile the application once … so running the following command should solve your problem:

      mvn exec:java -Dexec.mainClass=com.hascode.tutorial.mqtt.Main

      Article will be updated soon

    8. jesy Says:

      I wish use this server with Javascript client.
      do you know how to connect?

    9. cindy Says:

      Hi,
      Does this server support web sockets?

    Search
    Categories