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

Discussion in 'B4J Questions' started by CanguroCode, May 7, 2018.

Tags:
  1. CanguroCode

    CanguroCode 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

    Code:
    'MQTTUtils

    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"
        ConnectAndReconnect(clientID)
    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
            JSON.Initialize(
    BytesToString(Payload,0,Payload.Length,"UTF8"))
            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(0999999999))
            
    Dim mo As MqttConnectOptions
            mo.Initialize(MQTTUser, MQTTpass)
            
    Log("Trying to connect")
            client.Connect2(mo)
            
    Wait For Mqtt_Connected (Success As Boolean)
            
    If Success Then
                
    Log("Mqtt connected")
                client.Subscribe(subtop,
    1)
                
    Do While working And client.Connected
                    client.Publish2(
    "ping"Array As Byte(0), 1False'change the ping topic as needed
                    Sleep(5000)
                
    Loop
                
    Log("Disconnected")
            
    Else
                
    Log("Error connecting.")
            
    End If
            Sleep(
    5000)
        
    Loop
    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"),0False)
        
    Else
            
    Log(DateTime.Time(DateTime.Now) & " INFO_MQTTUtils: Publicacion no realizada, cliente no conectado al broker")
        
    End If
    End Sub

    Main Code
    Code:
    'Main
    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.
        MainForm.Show
        mqtt.Initialize(
    "usuario1""1234qweasd")
        mqtt.Request(
    "MyRequest")
        
    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: May 7, 2018
  2. Erel

    Erel Administrator Staff Member Licensed User

    What exactly do you want to wait for? What is mqtt.Request?
     
  3. CanguroCode

    CanguroCode 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)
     
  4. Erel

    Erel Administrator 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:

    Code:
    '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: May 8, 2018
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice