B4J Question How to use 'wait for' in a Mqtt Class


Active Member
Licensed User
I have a mqtt class for broker connection, send messages and receive messages.

The logic that I use is:
1. Client publish message to topic: "mytopic"
2. In the other side an Script is subscribed to the topic: "mytopic"
3. As soon as the message is received, the script publishes in: "response"
4. Client receives message and processes in "Sub MyFunction"

Everything works fine (if I follow the typical way), but for clarity of my code I would like to implement the 'wait for' function to stay waiting to receive a message, but my implementation is not correct, I use the following code (obviously it does not work):

MQTT Class


Sub Class_Globals
    Private fx As JFX
    Private client As MqttClient
    Private subtop, pubtop As String
    Public connected As Boolean
    Private MQTTUser, MQTTpass As String
    Private working As Boolean = True
End Sub

Public Sub Initialize( usuario As String, password As String, clientID As String)
    MQTTUser = usuario
    MQTTpass = password
    subtop = "response"
    pubtop = "mytopic"
End Sub

Public Sub  client_MessageArrived(Topic As String, Payload() As Byte)
    Dim JSON As JSONParser
    Dim content As List
    Dim head As String
    If Payload.Length > 0 Then
        content = JSON.NextArray
        head = content.Get(0)
        If head.Contains("MyString") Then
            Log("Go to MyFunction")
            CallSub2(Main, "MyFunction", content)
         End If
    End If
End Sub

Private Sub ConnectAndReconnect(clientID As String )
    Do While working
        If client.IsInitialized Then client.Close
        client.Initialize("mqtt", "ssl://io.adafruit.com:8883", "B4X" & Rnd(0, 999999999))
        Dim mo As MqttConnectOptions
        mo.Initialize(MQTTUser, MQTTpass)
        Log("Trying to connect")
        Wait For Mqtt_Connected (Success As Boolean)
        If Success Then
            Log("Mqtt connected")
            Do While working And client.Connected
                client.Publish2("ping", Array As Byte(0), 1, False) 'change the ping topic as needed
            Log("Error connecting.")
        End If
End Sub

Private Sub cliente_Disconnected
    connected = False
End Sub

Public Sub Request(solicitud As String, parametros As String)
    If connected Then
        Log(DateTime.Time(DateTime.Now) & " INFO_MQTTUtils: Publicando Solicitud")
        client.Publish2(pubtop, solicitud.GetBytes("UTF8"),0, False)
        Log(DateTime.Time(DateTime.Now) & " INFO_MQTTUtils: Publicacion no realizada, cliente no conectado al broker")
    End If
End Sub

Main Code
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Dim mqtt As MQTTUtils
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("principal") 'Load the layout file.
    mqtt.Initialize("usuario1", "1234qweasd")
    Wait For MyFunction(content as List)
    Log("Process Data from Wait For")
end sub

Sub MyFunction(content as List)
    Log("Process Data from MyFunction")
end sub

What is the right way?
Last edited:


Active Member
Licensed User
I'm Sorry, Mqtt Class edited. Request is a method from my Mqtt Class (MQTTUtils), I want wait for the mqtt MessageArrived or MyFunction (for the example, it's almost the same, I think) after client publish (mqtt.Request)


Staff member
Licensed User
All B4X developers must watch this tutorial:
If you want to call a method that sends a request and waits for the response:

'in the class
Public Sub SendRequest (data() As Byte) As ResumableSub
 'send the request
 Wait For client_MessageArrived(Topic As String, Payload() As Byte)
 'assuming that you want to return the payload. If you want to return both then use a custom type
 Return Payload
End Sub

'call this sub from main module:
Wait For (MyClass.SendRequest(...)) Complete (Payload() As Byte)
'work with payload
Last edited: