B4J Tutorial [IoT] MQTT Protocol

Status
Not open for further replies.
What is MQTT?

"MQTT is a Client Server publish/subscribe messaging transport protocol. It is light weight, open, simple, and designed so as to be easy to implement. These characteristics make it ideal for use in many situations, including constrained environments such as for communication in Machine to Machine (M2M) and Internet of Things (IoT) contexts where a small code footprint is required and/or network bandwidth is at a premium.

The protocol runs over TCP/IP, or over other network protocols that provide ordered, lossless, bi-directional connections." (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html)

I recommend all developers to learn the main concepts of MQTT. It is quite simple to use and it solves many of the real-world issues that developers need to manage when building network based solutions.

You can find good tutorials about MQTT here:

Some of the differences between MQTT solutions and B4J server (http and websocket) solutions:
  • With MQTT we only need to develop the clients. The server (message broker) is already implemented for us.
  • Each client can send messages (publish) and receive messages (subscribe). Note that we can implement a similar solution with WebSockets.
  • It is a many to many connection. Clients can listen to messages from other clients.
Server / Message Broker

The clients connect to the broker. The broker is responsible for routing the messages and managing the connections.
You can either run a local broker (for local network solutions) or an online broker.

You can install and run Mosquitto: http://mosquitto.org/download/
Pay attention to the installation instructions as it depends on two additional resources. Follow the links in the installation dialog.

CloudMQTT is an online broker: cloudmqtt.com
They provide a free plan which you can use during development. Very simple to get started with.
Edit: You can embed the broker in your app with the new MqttBroker library (B4A + B4J): https://www.b4x.com/android/forum/threads/mqttbroker.61548/

B4X Code

  1. Initialize MqttClient with the server URI and client id.
  2. Set the options, including the user name and password, if required.
  3. Call MqttClient.Connect
  4. The Connected event will be raised. If Success is true then you can subscribe to topics and publish messages.
  5. The MessageArrived event will be raised whenever a message is received (based on the subscribed topics).
  6. Call MqttClient.Close to close the connection. Make sure to close the connection before you close the app or the process may keep on running in the background.
See the attached example. You will need to set the user name and password based on your CloudMQTT account or change it to connect to a local broker.

You can compile it in release mode and run multiple instances of the application to see how it works.
See the video here: https://www.b4x.com/android/forum/threads/mqtt.59346/

Note that the jMQTT library is compatible with B4A and B4J.
The library is available here: https://www.b4x.com/android/forum/threads/jmqtt-official-mqtt-client.59472/
B4i - iMQTT library: https://www.b4x.com/android/forum/threads/imqtt-official-ios-mqtt-client.59516/

A compiled example is available here: https://www.b4x.com/android/forum/threads/mqtt.59346/#post-374535
 

Attachments

  • MQTTExample.zip
    2.7 KB · Views: 5,261
Last edited:

rboeck

Well-Known Member
Licensed User
Longtime User
One question for retained objects - i have used this option and now i want to delete all the pending messages. As i unterstand, i have to send a new message with the same topic with a zero byte payload.

So i tried to send this with
B4X:
MQtt.Publish(mytopic,serializator.ConvertObjectToBytes(Null))

and this had no effect. Then i tried to directly send Null, but i got only syntax errors.
How can i send a zero byte payload?
 

Roberto P.

Well-Known Member
Licensed User
Longtime User
Thanks Erel
very interesting.
Could you help me understand briefly cases of use of this system and the difference compared to web-socket chat?
I sense that this technology can be used for notifications, correct? or to exchange messages, chat type, correct?
it would be very helpful to understand also the advantages and disadvantages of this system.
Thank you in advance
Greetings
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
There are cases where it is very clear. For example if you want to use browsers as clients then you need to use WebSockets.

If you have a large solution based on a http server then it also makes sense to use WebSockets.

WebSockets is a client / server channel. MQTT connects multiple clients.

If you are using a low level network solution (TCP + AsyncStreams) then you should consider switching to MQTT.

Running a publicly accessible MQTT broker on the internet is less secure compared to a web server.

Real push notifications should be implemented with GCM (Android)or APN (iOS).

These are just several points. I recommend you to try the examples to get a better feeling of this technilogy.
 

avalle

Active Member
Licensed User
Longtime User
On top of Erel's comments, I would add the following to explain why MQTT is a superior protocol to WebSockets, at least for IoT applications, multi-client access to a single resource or embedded hardware/microcontroller applications.
  • MQTT is a publish/subscribe protocol with support of QoS (Quality of Service). You can decide the QoS level based on how critical is your application and then get rid of redundancy if not required.
  • MQTT uses a binary format, while HTTP is based on (expanded) text strings. Binary is more efficient and uses less data/memory/bandwidth.
  • MQTT is a lightweight protocol, created specifically for small footprint, thus ideal for embedded hardware and microcontroller who have limited resources, especially flash memory for code and RAM. As an example, a message header in MQTT only uses 2 bytes, while HTTP can use dozen or even hundreds of bytes.
  • Lightweight also means less CPU cycles to execute, turning into lower power supply requirements, a critical aspect for battery operated devices and mobile clients.
Regards
Andrea
 

AzureCrystal

Member
Licensed User
Longtime User
What is MQTT?
Great library and tutorial, got it working with CloudMQTT, I can do circles on any number of devices, but when I send a the message "clear"(or any other text using same topic) via the CloudMQTT websocket console it fails, shouldn't this code work for a passed string as well? Grateful thanks for any insights ;)

B4X:
Private Sub mqtt_MessageArrived (Topic As String, Payload() As Byte)
   Dim obj As Object = serializator.ConvertBytesToObject(Payload) '<---fails here
   If obj Is CircleData Then
     If Topic = mytopic Then Return 'the circle was already drawn
     Dim cd As CircleData = obj
     DrawCircleData(cd)
   Else 'obj is string
     Dim s As String = obj
     Select s
       Case "clear"
         Canvas1.DrawColor(Colors.Black)
         Activity.Invalidate
       Case "close"
         Activity.Finish
     End Select
   End If
End Sub
 

AzureCrystal

Member
Licensed User
Longtime User
Never mind, I just saw the video of the B4J example and the text commands are coming from the B4J client, not from a generic MQTT chat window...
Wow, this is fast and opens a whole array of possibilities, great stuff Erel.
 
Last edited:

JakeBullet70

Well-Known Member
Licensed User
Longtime User
Never mind, I just saw the video of the B4J example and the text commands are coming from the B4J client, not from a generic MQTT chat window...
Wow, this is fast and opens a whole array of possibilities, great stuff Erel.

I have been working with MQTT for about a 1 1/2 year. And yeah, the possibilities are endless.
 

Danbicky

Member
Licensed User
Longtime User
Erel,

I have the same problem, I am sending the command clear from my mqtt broker as a string and as soon as it is arrived by the app i get the same error as azure above.

Dim obj As Object = serializator.ConvertBytesToObject(Payload) '<---fails here

Throws a java io error

How can this be resolved? I simply want to send commands from the broker to the android app for notification of events.

Thanks

Dans
 

Danbicky

Member
Licensed User
Longtime User
This question is the same as azure's and seems related to this thread?, sorry I do post through a client to the broker using node red interface, message is sent to broker by node red, message is received on subscribed topic by client in android app and fails with the error as listed above.

Dans
 

techknight

Well-Known Member
Licensed User
Longtime User
I know this is an older thread, but I am posting this as a heads up:

I am going to save anyone new here hours of headache: The latest openSSL light 1.1.X does NOT come with the correct files needed for mosquito to run. Neeed the older 1.0 and earlier version. Not sure when or IF they will fix it.
 
Status
Not open for further replies.
Top