B4A Library MQTT - MQ Telemetry Transport for B4A

MqttTop.jpg


This library was made based on MQTT Protocol


Installation instructions:
- Copy the .xml and .jar(s) files to your custom libraries folder
- Select in your REFERENCED LIBRARIES


MqttRef.png




Version history:
V1.0.0 (First public release - Donationware):
- Initial version

V1.0.2 (Release - Donationware):
- Implement method to get independence of threads

V1.0.4 (Release - Donationware):
- Implement method to subscribe a topic with QoS

V1.0.5 (Release - Donationware):
- Now can be used isConnected method "BEFORE" the first connection

V1.0.6
(Release - Donationware):
- not published

V1.0.7 (Release - Donationware):
- New methods: Publish2, Subscribe3, Subscribe4
This new methods return the token, then after when arrived or publish the messages, you can compare

MQTT
Author:
Alberto Iglesias - [email protected]
Version: 1.07
  • MQTT
    Events:
    • connectionlost ( )
    • deliverycomplete (Token As String)
    • messageArrived (Topic As String, Message As String)
    • onConnect (Status as boolean As )
    • onDisconnect (Status as boolean As )
    • onInitialized ( )
    Fields:
    • CleanSession As Boolean
    • JavaDebug As Boolean
    • KeepAliveInterval As Int
    • QoS_AtLeastOnce As Int
    • QoS_AtMostOnce As Int
    • QoS_ExactlyOnce As Int
    • generatedClientId As String
    Methods:
    • About As String
    • Connect (broker As String, ClientID As String, Username As String, Password As String) As Boolean
    • Disconnect As Boolean
    • Initialize (eventname As String)
    • Publish (Topic As String, Message As String, Qos As Int, Retained As Boolean)
    • Publish2 (Topic AsString, Message AsString, Qos AsInt, Retained AsBoolean)
    • Subscribe (Topic As String)
    • Subscribe2 (Topic As String, QoS as int)
    • Subscribe3 (Topic As String)
    • Subscribe4 (Topic As String, QoS as int))
    • Unsubscribe (Topic As String)
    • Version As String
    • isConnected As Boolean
    Permissions:
    • android.permission.ACCESS_WIFI_STATE
    • android.permission.INTERNET


MqttSample1.png



MqttRef2.png



How works the MQTT protocol
MqttScheme1.jpg



Communication Infrastructure

MqttScheme2.png



References:
http://mqtt.org/
http://public.dhe.ibm.com/software/dw/webservices/ws-mqtt/mqtt-v3r1.html
Mosquitto Broker: http://mosquitto.org/



* This version is fully functional, the only one difference is when publishing a message the text "Donationware" is delivery with your message.
Please consider a simple €10 donation and I send to you the Library without "Donationware" text in a publish method.

Already available in B4J too:
https://www.b4x.com/android/forum/threads/mqtt-mq-telemetry-transport-for-b4j.48184/

Already available in B4i too:
https://www.b4x.com/android/forum/threads/mqtt-mq-telemetry-transport-for-b4i.50036/


 

Attachments

  • MQTTB4ASample.zip
    7.8 KB · Views: 864
  • MQTT Library1.0.2.zip
    162 KB · Views: 552
  • MQTTSampleActivity.zip
    8.2 KB · Views: 675
  • SampleSubscribe2.zip
    8.3 KB · Views: 625
  • MQTT Library1.0.4.zip
    154.6 KB · Views: 469
  • MQTT Library1.0.5.zip
    154.9 KB · Views: 509
  • SampleIsConnected.zip
    8.3 KB · Views: 716
  • SampleWithToken.zip
    8.2 KB · Views: 505
  • MQTT Library1.0.7.zip
    155.6 KB · Views: 918
Last edited:

klarsys

Active Member
Licensed User
Longtime User
Also, I do not get any call back if connection attempt fails.

e.g. If I call Connect when there is no network available, I do not get any call back.

If you can give a call back, I can use it to retry connection.
I can use timer but that's not a good practice and it may introduce race conditions.
 

klarsys

Active Member
Licensed User
Longtime User
I get that call back once connected.

Have you tried connecting without any active network connections?
 

klarsys

Active Member
Licensed User
Longtime User
I have two observations:
1. Sometimes, objMqtt.connect returns false immediately. This generally happens if it is known that there is no network availability.
2. Sometimes, objMqtt.connect returns false after a long timeout. This generally happens if server is unreachable or network connection is flaky (mobile data coverage issue).

In second case, my app freezes in objMqtt.connect call and sometimes it even gets killed by android.

I want to avoid app getting frozen. I guess to do that objMqtt.connect should be called from a different task? How do I do that?
 

Alberto Iglesias

Well-Known Member
Licensed User
Longtime User
hello,

1. Sometimes, objMqtt.connect returns false immediately. This generally happens if it is known that there is no network availability.

yes, this is correct

2. Sometimes, objMqtt.connect returns false after a long timeout. This generally happens if server is unreachable or network connection is flaky (mobile data coverage issue)

yes, this too is correct.


depends much of the Mqtt broker, because some have others controls to tell to client is a live, and they timeouts of latency is different...
 

klarsys

Active Member
Licensed User
Longtime User
depends much of the Mqtt broker

No, this is client side issue. Since objMqtt.connect is a blocking call and it may freeze the app for indeterminate time based on network conditions, it should be called from an async task (just like any other network connection).

My app is getting several ANR reports due to this issue.

Here is a simple way to reproduce it (I used the example app provided with the library):
1. Connect phone to internet through a WiFi router.
2. Build, install and test example app to make sure it is working as expected.
3. Remove internet access to the WiFi router (I just pulled the ethernet cable out of it) so that phone is connected to WiFi but there is no connectivity to internet.
4. Start the example app and try to connect. App will freeze at this time and after certain timeout Android will report that the app is not responding.

Please consider moving it to an async task.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
is there any way in B4A to run MQTT.connect() in a separate task?
The library itself should implement network communication correctly in the background (like all the official libraries).

You can use the Threading library to call this method from a background thread. However it is impossible to say whether it will work reliable or not without going over the library source code.
 

Dave Roffey

New Member
Licensed User
Longtime User
Hi Alberto,
This is great library for me, now I have the very app I need because of this.
I have sent a donation through, so would appreciate the donate free version.

** Hmmmm. Yes..... always remember to check spam & junk boxes! ..... its been sitting there waiting!

Thanks
 
Last edited:

Dave Roffey

New Member
Licensed User
Longtime User
Hi Alberto,
The trial version works fine, but full version only seems to work in debug mode? As a novice here, I wonder if you could throw any light on that for me.
Full xml had permissions missing, but then only connects and subscribes once, publish once and disconnects, in that order. Picks up last publish. All very strange. Back to Donate text for now then and filter it out.
 
Last edited:

klarsys

Active Member
Licensed User
Longtime User
Hi @Alberto Iglesias, please consider moving mqtt.connect to async task.

Hi @Erel, can BA.runAsync be helpful here? Can I use it to call MQTT.Connect() from Basic / inline Java code to make it run in a separate task so that ANR can be avoided?
 

Dave Roffey

New Member
Licensed User
Longtime User
Disappointed with the lack of any sort of reply for help after donation .... ah well..... all sorted with a alternate and free library. Thanks
 

Aidan Ruff

Member
Licensed User
Longtime User
Hi Alberto.
I haven;t been doing much with b4a for a few months, but I've just upgraded to the latest version and I have a slight problem with the mqtt lib. I can connect to a broker, subscribe to a topic and receive messages, but when I try to send one, I get the following error:-

JAVA [Connect]
JAVA [Connect] generatedClientId = paho93225944984010
JAVA [Connect] broker = tcp://46.101.34.29:1883
JAVA [Connect]:Connected = true
[objMqtt_onConnect] Status = true
[objMqtt_onConnect] generatedClientId = paho93225944984010
[Connection attempt] true

JAVA [Subscribe] Topic = aidans_desktop/toesp
JAVA [messageArrived] topic = aidans_desktop/toesp
JAVA [messageArrived] message = {pwm:0,80,0,55}
[objMqtt_messageArrived] Topic = aidans_desktop/toesp / Message = {pwm:0,80,0,55}

JAVA [Publish] Message = {ext:"Hello b4a"}
JAVA [Publish]:MqttException:Connection lost (32109) - java.io.EOFException
JAVA [connectionLost]
[objMqtt_connectionLost]


Any ideas what might be the problem - I've even tried messages without embed double quotes in case that the issue
Regards
Aidan
 

leitor79

Active Member
Licensed User
Longtime User
Hi Alberto,

I've started with MQTT yesterday after months of GCM failures.

I'm running a local mosquitto server. I've managed to connect, subscribe and get published messages; however I can't (don't know how?) to receive messages published when I'm disconnected. I'm using QOS=2 on the publish and on the subscription. Like this:

- connect the device (Dim strBroker As String = "tcp://192.168.1.125:1883" Dim bRet As Boolean = objMqtt.Connect(strBroker,"","",""))
- subscribe to topic with qos=2 (objMqtt.Subscribe2(txtSubscribe.text,2))
- publish with mosquitto_pub (with -q 2), message is received on my device
- disconnect the device
- publish with mosquitto_pub again (same exact as the previous time)
- connect the device again, message is not received
- subscribe again, message is not received

what am I missing?


thank you very much!
 

javiers

Active Member
Licensed User
Longtime User
Hello, Alberto.
Please review the link to the donation of the library in B4A. It takes you to the B4J library. I made the donation to both (B4J and B4A), but in the second I received the library to B4J again.

I've sent you an email.

I wait your answer. Thank you.


Si toda la información es correcta, puede enviar el donativo.

FinalidadImporte del donativoTotal
Library - Visual Net
Referencia:B4JLIBMQTT
 

javiers

Active Member
Licensed User
Longtime User
Hello Alberto , is there any way to intercept a message MQTT , when the application is in the background?

Another question. When the app is in background , you may be sending a message from time to time to indicate to the application on the device B4J is alive ?

Thanks for your answer.
 
Top