Android Question [SOLVED] Mqtt LastWill message never arrives subscribed client

knutf

Active Member
Licensed User
Longtime User
Hello

I am struggling to understand how to use the lastwill message system in mqtt.
I believe that the lastwill message work like this:
'
If we have a topic:
Dim TopicClientBWill As String = "ClientBWill"

-and clientA subscribed to this topic:
clientA.Subscribe(TopicClientBWill,1)

-and clientB is connected with a desire for a LastWill like this:
Dim options As MqttConnectOptions
options.Initialize("","")
options.SetLastWill(TopicClientBWill,PayloadClientBWill,1,True)
clientB.Connect2(options)

-and you end clientB like this:
clientB.Close

Then the event for clientA will be fired.

But I can't get this to work. Can someone help me. I've made a short B4X project showing that the clientA_MessageArrived is not fired for TopicClientBWill. The code in the project and log is shown below. The project is also attached.

Can someone help me?



B4X:
#Region Shared Files
#CustomBuildAction: folders ready, %WINDIR%\System32\Robocopy.exe,"..\..\Shared Files" "..\Files"
'Ctrl + click to sync files: ide://run?file=%WINDIR%\System32\Robocopy.exe&args=..\..\Shared+Files&args=..\Files&FilesSync=True
#End Region

'Ctrl + click to export as zip: ide://run?File=%B4X%\Zipper.jar&Args=Project.zip

Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private MqttBroker As MqttBroker
    Private clientA As MqttClient
    Private clientB As MqttClient
    Private bc As ByteConverter
End Sub

Public Sub Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.



Private Sub Button1_Click
    Dim TopicClientBWill As String = "ClientBWill"
    Dim PayloadClientBWill() As Byte = "Stoped".GetBytes("AscII")

    Dim TopicCLientBStarted As String = "ClientBStarted"
    Dim PayloadClientBStarted() As Byte = "Started".GetBytes("AscII")

    Dim BrokerURI As String = "tcp://localhost:1883"
 
 
    MqttBroker.Initialize("broker",1883)
    MqttBroker.DebugLog = False
    MqttBroker.Start
 
    Log("ClientA Connect to broker")
    clientA.Initialize("clientA",BrokerURI,"clientA")
    clientA.Connect
 
    Wait For clientA_Connected (Success As Boolean)
    Log($"clientA_Connected(${Success})"$)
    clientA.Subscribe(TopicCLientBStarted,1)
    clientA.Subscribe(TopicClientBWill,1)
 
    clientB.Initialize("clientB",BrokerURI,"clientB")
    Dim options As MqttConnectOptions
    options.Initialize("","")
    options.SetLastWill(TopicClientBWill,PayloadClientBWill,1,True)
    clientB.Connect2(options)
 
    Wait For clientB_Connected (Success As Boolean)
    Log($"clientB_Connected(${Success})"$)
    clientB.Publish2(TopicCLientBStarted,PayloadClientBStarted,1,True)
 
    Sleep(5000)
 
    clientB.Close
    Wait For clientB_Disconnected
    Log("clientB_Disconnected")
 
End Sub

Private Sub clientA_MessageArrived (Topic As String, Payload() As Byte)
    Dim bc As ByteConverter
    Log($"clientA_MessageArrived Topic:${Topic}  Payload:${bc.StringFromBytes(Payload,"AscII")}"$)
End Sub

And this is the log when the button is pushed:

The log shows that clientA_MessageArrived was not fired with subject ClientBWill after clientB was disconnected.
 

Attachments

  • Test.zip
    10.2 KB · Views: 127
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
Upvote 0

XorAndOr

Active Member
Licensed User
Longtime User
The example doesn't cause the broker to send the last will message because the client disconnects gracefully by calling client.Close. It will only be sent if the client disconnects without calling close.
Thanks @Erel for the explanation, it's much clearer now
have a nice day
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…