B4A Library JG MQTT Library

Hi all,

This is my very first library :)

It implements MQTT standard V3.1.1

MQTT is a lightweight publish/subscribe messaging protocol.

for further information see http://mqtt.org/.

MQTT_pubsub.jpg


Publish/Subscribe
The MQTT protocol is based on the principle of publishing messages and subscribing to topics, or "pub/sub". Multiple clients connect to a broker and subscribe to topics that they are interested in. Clients also connect to the broker and publish messages to topics. Many clients may subscribe to the same topics and do with the information as they please. The broker and MQTT act as a simple, common interface for everything to connect to.

Quality of Service
MQTT defines three levels of Quality of Service (QoS). The QoS defines how hard the broker/client will try to ensure that a message is received.

Implemented levels are :

  • 0: The broker/client will deliver the message once, with no confirmation.

  • 1: The broker/client will deliver the message at least once, with confirmation required.

  • 2: The broker/client will deliver the message exactly once by using a four step handshake.
Clean session / Durable connections
On connection, a client sets the "clean session" flag, which is sometimes also known as the "clean start" flag. If clean session is set to false, then the connection is treated as durable. This means that when the client disconnects, any subscriptions it has will remain and any subsequent QoS 1 or 2 messages will be stored until it connects again in the future. If clean session is true, then all subscriptions will be removed for the client when it disconnects.

Limitation : Persistency of sessions is not implemented yet on the client side (this library)

Retained Messages
All messages may be set to be retained. This means that the broker will keep the message even after sending it to all current subscribers.

Last Will Testament
When a client connects to a broker, it may inform the broker that it has a will. This is a message that it wishes the broker to send when the client disconnects unexpectedly.


Version 1.0

This is the first release. It is provided with a very basic sample test App.

The use is totally free, with no limitation.

Utilisation

Connect to a broker (here iot.eclipse.org)

B4X:
MyMQTT.Connect("iot.eclipse.org","1883", "test", "", "", "/android/", "dead", 0, False, True, 60)

Events :
MQTT_events.jpg



Methods :
MQTT_methods.jpg


test App :

MQTT_App.jpg

it is limited to :
  • connect/disconnect to broker and pinging to test connection
  • sending/receiving messages
  • subscribing/unsubscribing to topics
  • selecting QoS

Enjoy !
And give me your feedback
 

Attachments

  • JG_MQTT_V1.0.zip
    12.2 KB · Views: 632

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi,
Online help should appear when typing the "connect(" word.

Here is the answer
Mqtt_hlep.jpg

Note that "clean session" is not implemented on the library side...
 

Tem

Member
Licensed User
Longtime User
Sorry, I'm a poor seeker .....

Another question. Because login and password are sending in plain text, I would like to use secure connction.
Any idea. how to use SSL?
 

freedom2000

Well-Known Member
Licensed User
Longtime User
That's a very good question. :)

Unfortunately I don't know... If you find a wait I can easy mod the library to introduce this feature.
 

javiers

Active Member
Licensed User
Longtime User
Hi,
I made a Windows tool to test various things around MQTT. Hope it's usefull.
Settings are stored in local ini-file.

Excellent work. You can make your program in B4J ?
O serves your library for B4J too?

Congratulations on your work.
 

gprandst

Member
Licensed User
Longtime User
Hi,
sorry, my code is Delphi7, as you can see from the icon. It uses some network layer libs and I must say, I haven't a clue how to do this in Java. But Delphi code, including MQTT properties, is no problem if you can do anything with it. Feel free to give any suggestions how to improve.

Best regards,
Gottfried
 

javiers

Active Member
Licensed User
Longtime User
Thanks for your answer. I wanted to make a desktop application using B4J .

freedom2000 , would be great if you could make JG MQTT Library for B4J .

A greeting.
 

TommyBee

Member
Licensed User
Longtime User
#freedom2000
Great work my Friend, i did a testapp for my ESP's in a few hours. Thank's a lot for that library and that it's free.
:):):):):):):):)
PS:
I always thought that "clean session" is only handled on the Server-Side. Client just have to tell it to the Broker at Connect-time, that's all :confused:?
 

freedom2000

Well-Known Member
Licensed User
Longtime User
#freedom2000
Great work my Friend, i did a testapp for my ESP's in a few hours. Thank's a lot for that library and that it's free.
:):):):):):):):)
PS:
I always thought that "clean session" is only handled on the Server-Side. Client just have to tell it to the Broker at Connect-time, that's all :confused:?

Thank you !

Beware however that there is still a bug if you retain messages on the server, it can send them in a burst when you connect next time and my lib is not yet robust to this... I have ta find time to fix it !
 

javiers

Active Member
Licensed User
Longtime User
Hello, with this code, the connection to the server fails.



B4X:
Sub Service_Start (StartingIntent As Intent)
    MyMQTT1.Initialize(Me, "MQTT1")
    serv_broker = "iot.eclipse.org"
    serv_puerto = "1883"
    serv_ID = "JG"
'    serv_broker = Main.broker_serv
'    serv_puerto =   Main.puerto_serv
'    serv_ID =   Main.id_serv   
    MyMQTT1.Connect(serv_broker,serv_puerto,serv_ID, "", "", "/mytest/", "dead", 0, False, True, 60)


'    MyMQTT1.Connect("iot.eclipse.org","1883", "JG", "", "", "/mytest/", "dead", 0, False, True, 60)
    LogColor("servidor Servicio : " & serv_broker, Colors.red)
    LogColor("puerto Servicio : " & serv_puerto, Colors.Green)
    LogColor("id Servicio : " & serv_ID, Colors.Green)

   
Timer2.Initialize("Timer2", 3000)
Timer2.Enabled = True   

End Sub

But this does not (global variables have the same content as the previous ... Main.broker_serv is the result of reading a SQL field with the value "iot.eclipse.org", including the double comma).


B4X:
Sub Service_Start (StartingIntent As Intent)
    MyMQTT1.Initialize(Me, "MQTT1")
'    serv_broker = "iot.eclipse.org"
'    serv_puerto = "1883"
'    serv_ID = "JG"
    serv_broker = Main.broker_serv
    serv_puerto =   Main.puerto_serv
    serv_ID =   Main.id_serv   
    MyMQTT1.Connect(serv_broker,serv_puerto,serv_ID, "", "", "/mytest/", "dead", 0, False, True, 60)


'    MyMQTT1.Connect("iot.eclipse.org","1883", "JG", "", "", "/mytest/", "dead", 0, False, True, 60)
    LogColor("servidor Servicio : " & serv_broker, Colors.red)
    LogColor("puerto Servicio : " & serv_puerto, Colors.Green)
    LogColor("id Servicio : " & serv_ID, Colors.Green)

   
Timer2.Initialize("Timer2", 3000)
Timer2.Enabled = True   

End Sub


I want the value of the server, port and topic are stored in a SQLite table, read to start the main module, and used to start the service. This would allow to modify the connection settings by the user.

Any ideas?

Thanks in advance...
 

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi,

I can't see any reason why it doesn't work but a bad declaration of variables.

Here is the syntax for connection :

B4X:
Public Sub Connect(aServer As String, aPort As String, aClientID As String, aUser As String, aPassword As String, aWillTopic As String, aWillMessage As String,  aQos As Int,  aRetain As Boolean, aCleanSession As Boolean, TimeOut As Int)

As you can see most of the variables are strings
Try to dump your variables to see if the string is correct...
 

javiers

Active Member
Licensed User
Longtime User
Hi,

I can't see any reason why it doesn't work but a bad declaration of variables.

Here is the syntax for connection :

B4X:
Public Sub Connect(aServer As String, aPort As String, aClientID As String, aUser As String, aPassword As String, aWillTopic As String, aWillMessage As String,  aQos As Int,  aRetain As Boolean, aCleanSession As Boolean, TimeOut As Int)

As you can see most of the variables are strings
Try to dump your variables to see if the string is correct...

Solved!
I included in the connection string "tcp: //".

Thanks for your answer. Great job!
 

Danbicky

Member
Licensed User
Longtime User
Hi JP,

Have you managed to add the On-disconnect command to this library?
Possibly you have an example that checks for connection and re connects if the connection has dropped?

Cheers buddy

Dans
 

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi JP,

Have you managed to add the On-disconnect command to this library?
Possibly you have an example that checks for connection and re connects if the connection has dropped?

Cheers buddy

Dans
Hi,

No there is no "OnDisconnect" event...

And at the moment I don't see a good reason to add it :)

You already have the "keepalive" parameter to send a Ping to the server to check the connection.
This generates the "OnPing" event.
 

Danbicky

Member
Licensed User
Longtime User
Hi,

No there is no "OnDisconnect" event...

And at the moment I don't see a good reason to add it :)

You already have the "keepalive" parameter to send a Ping to the server to check the connection.
This generates the "OnPing" event.


Hi JP,

If the connection to a server has not been connected, calling the MQTT.ping function does not return an event within MQTT_OnPing, this only fires an event
if MQTT has attempted a connection.

Thanks for your response anyway.

Dan
 

freedom2000

Well-Known Member
Licensed User
Longtime User
Hi JP,

If the connection to a server has not been connected, calling the MQTT.ping function does not return an event within MQTT_OnPing, this only fires an event
if MQTT has attempted a connection.

Thanks for your response anyway.

Dan
Hi again,

If not connected then you have not received the OnConnect event :)

And if not connected you would never receive the OnDisconenct event either... Do I miss a point ?
 

Danbicky

Member
Licensed User
Longtime User
Sorry JP I did not make it clear.

My aim is to add the MQTT code to a service. A timer will be enabled to check if MQTT has a connection and if not to re establish this connection.
Playing with your example, I added a timer and run the application. I was relying on the fact that an event would be raised in the _Onping function if
no ping was returned.

Since then I have added a string variable:


B4X:
Sub MQTT_OnConnect(val As String)
    Log("Connect : " & val)
    TxtConn.Text = val
    LogColor("Connected to Broker OK",Colors.Green)
    MyMQTT.Subscribe(TxtSubscribe.text,SpQoS.SelectedIndex)
    MyMQTT.Publish(TxtTopic.Text, TxtMessage.Text, SpQoS.SelectedIndex,False)   
End Sub



B4X:
Sub TmrMQTT_Tick
    ' timer fired
    LogColor("Checking Connection",Colors.Blue)
    MyMQTT.Ping
       
      If (MQTT_Online = "PingOk") Then
        LogColor("Connection is Good",Colors.Green)
        End If
       
        If (MQTT_Online = "") Then   
        LogColor("No connection to Broker",Colors.Red)
        LogColor("Attempt Reconnection",Colors.Red)   
        MyMQTT.Connect("iot.eclipse.org","1883", "test", "", "", "/android/", "dead", 0, False, True, 60)
       
        End If

The idea is that the time will restore a connection and keep MQTT connected in the background. If specific messages are received then an alert will
be raised to notify the user.

Any help would be appreciated.

Cheers Dans
 

freedom2000

Well-Known Member
Licensed User
Longtime User
The OnPing event is already generated by the library using an internal timer.
It is needed to "keep alive" the connection at the priod specified byu the "keepalive" parameter.

Anytime the internal timer is trigger you should receive a OnPing event.

What I would do is :

Arm a timer "yourTimer" to trigger an alarm with a period greater than "keepAlive"

clear the timer in the OnPing event
B4X:
Sub MQTT_OnPing(val As String)
    yourTimer.enabled = false
    yourTimer.enabled = true
End Sub
 
Top