Android Question JMQTTBroker V1 (B4A compatible) with Events ?

Mike1970

Well-Known Member
Licensed User
Longtime User
Hi everyone!
I'm developing an Android application that needs a local MQTT broker.

However, the v1 broker compatible with android is very very limited...
I wanted to ask if someone here in the forum owns an edited library that supports broker events like ClientConnected, ClientDisconnected, etc...

It would be awesome to have an improved MQTT android-compatible broker, I think it is missing.

Thanks in advance!
 

WebQuest

Active Member
Licensed User
Longtime User
🔁 1. you can use an internal MQTT client as a "monitor"
You can create a second instance of MQTTClient in the same app (or in a separate app) that connects to the broker as any client, subscribes to all topics (#) and acts as an “observer”.

B4X:
mqttClient.Subscribe("#", 0)
on event
B4X:
Sub mqttClient_MessageArrived (Topic As String, Payload() As Byte)
    Log("Messaggio arrivato: " & Topic & " → " & BytesToString(Payload, 0, Payload.Length, "UTF8"))
End Sub
This way you “simulate” the MessageArrived event even if it is not emitted by the broker, but received by the client.
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
🔁 1. you can use an internal MQTT client as a "monitor"
You can create a second instance of MQTTClient in the same app (or in a separate app) that connects to the broker as any client, subscribes to all topics (#) and acts as an “observer”.

B4X:
mqttClient.Subscribe("#", 0)
on event
B4X:
Sub mqttClient_MessageArrived (Topic As String, Payload() As Byte)
    Log("Messaggio arrivato: " & Topic & " → " & BytesToString(Payload, 0, Payload.Length, "UTF8"))
End Sub
This way you “simulate” the MessageArrived event even if it is not emitted by the broker, but received by the client.
Yes this is what I have already done :D
This workaround is for the equivalent of an PublishedMessage event.

However, what would be really useful are the events like "NewClientConnected", "ClientDisconnected" that are not "workaroundable"
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This code implements the interface that listens to broker events. It was tested with MqttBroker v2 and it looks like the connected and disconnected events aren't raised.

You can try it:
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Broker As MqttBroker
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")
    Broker.Initialize("broker", 55555)
    Dim server As JavaObject = Broker.As(JavaObject).GetField("server")
    Dim pck As String = GetType(Me) & "$MyHandler"
    Dim handler As JavaObject
    handler.InitializeNewInstance(pck, Array(Me))
    Dim handlers As List = Array(handler)
    server.RunMethod("startServer", Array(Broker.As(JavaObject).GetField("config"), handlers))
End Sub

Private Sub Broker_Connect (Msg As Object)
    Log("Connect: " & Msg)
End Sub

Private Sub Broker_Disconnect (Msg As Object)
    Log("Disconnect: " & Msg)
End Sub

Private Sub Broker_ConnectionLost (Msg As Object)
    Log("ConnectionLost: " & Msg)
End Sub
Private Sub Broker_Publish (msg As Object)
    Log("Publish: " & msg)
End Sub
Private Sub Broker_Subscribe (msg As Object)
    Log("Subscribe: " & msg)
End Sub
Private Sub Broker_Unsubscribe (msg As Object)
    Log("Unsubscribe: " & msg)
End Sub
Private Sub Broker_MessageAcknowledged (msg As Object)
    Log("MessageAcknowledged: " & msg)
End Sub

#if Java
import io.moquette.interception.messages.*;
public static class MyHandler implements io.moquette.interception.InterceptHandler {
    BA ba;
    public MyHandler(B4AClass parent) {
        this.ba = parent.getBA();
    }
     public String getID() {
        return "handler";
    }

    public Class<?>[] getInterceptedMessageTypes() {return ALL_MESSAGE_TYPES;}

    public void onConnect(InterceptConnectMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_connect", msg);
    }

    public void onDisconnect(InterceptDisconnectMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_disconnect", msg);
    }

    public void onConnectionLost(InterceptConnectionLostMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_connectionlost", msg);
    }

    public void onPublish(InterceptPublishMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_publish", msg);
    }

    public void onSubscribe(InterceptSubscribeMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_subscribe", msg);
    }

    public void onUnsubscribe(InterceptUnsubscribeMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_unsubscribe", msg);
    }

    public void onMessageAcknowledged(InterceptAcknowledgedMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_messageacknowledged", msg);
    }
}
#End If
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
This code implements the interface that listens to broker events. It was tested with MqttBroker v2 and it looks like the connected and disconnected events aren't raised.

You can try it:
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private Broker As MqttBroker
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")
    Broker.Initialize("broker", 55555)
    Dim server As JavaObject = Broker.As(JavaObject).GetField("server")
    Dim pck As String = GetType(Me) & "$MyHandler"
    Dim handler As JavaObject
    handler.InitializeNewInstance(pck, Array(Me))
    Dim handlers As List = Array(handler)
    server.RunMethod("startServer", Array(Broker.As(JavaObject).GetField("config"), handlers))
End Sub

Private Sub Broker_Connect (Msg As Object)
    Log("Connect: " & Msg)
End Sub

Private Sub Broker_Disconnect (Msg As Object)
    Log("Disconnect: " & Msg)
End Sub

Private Sub Broker_ConnectionLost (Msg As Object)
    Log("ConnectionLost: " & Msg)
End Sub
Private Sub Broker_Publish (msg As Object)
    Log("Publish: " & msg)
End Sub
Private Sub Broker_Subscribe (msg As Object)
    Log("Subscribe: " & msg)
End Sub
Private Sub Broker_Unsubscribe (msg As Object)
    Log("Unsubscribe: " & msg)
End Sub
Private Sub Broker_MessageAcknowledged (msg As Object)
    Log("MessageAcknowledged: " & msg)
End Sub

#if Java
import io.moquette.interception.messages.*;
public static class MyHandler implements io.moquette.interception.InterceptHandler {
    BA ba;
    public MyHandler(B4AClass parent) {
        this.ba = parent.getBA();
    }
     public String getID() {
        return "handler";
    }

    public Class<?>[] getInterceptedMessageTypes() {return ALL_MESSAGE_TYPES;}

    public void onConnect(InterceptConnectMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_connect", msg);
    }

    public void onDisconnect(InterceptDisconnectMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_disconnect", msg);
    }

    public void onConnectionLost(InterceptConnectionLostMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_connectionlost", msg);
    }

    public void onPublish(InterceptPublishMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_publish", msg);
    }

    public void onSubscribe(InterceptSubscribeMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_subscribe", msg);
    }

    public void onUnsubscribe(InterceptUnsubscribeMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_unsubscribe", msg);
    }

    public void onMessageAcknowledged(InterceptAcknowledgedMessage msg) {
        this.ba.raiseEventFromUI(this, "broker_messageacknowledged", msg);
    }
}
#End If
Hi Erel! How are you?

Thank you very much for the answer.
I re-installed the v2* of the mqtt broker, then I added your snippet and unfortuntely, as you said, the events to which I was more interested in does not work 😂 (onConnect and onDisconnect).

Instead I confirm that onSubscribe and onPublish fires... I did not tested the other because I noticed that the returned values are un-usable since their class is "InterceptxxxxxMessage"... or better... I do not know how to decode/parse/cast them.

Screenshot 2025-06-24 alle 09.45.31.png





* In the original post of mqtt broker it says that the v2 is not compatible with B4A, initially I didn't see that line and installed it anyway. It worked but often I was getting error logs coming from the library saying something like "Closing netty channel. Cid ..." (I do not know if it could be it).

I want to point out also that enabling the DebugLogs of the v1 I can see that this version internally has the connection/disconnection events too.

Screenshot 2025-06-24 alle 09.55.34.png



I hope that this thread will be the spark that will produce a better Mqtt Broker for Android for everyone once for all 💪🏼😂
 
  • Like
Reactions: byz
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
What I meant was that you try it with v1, though it is less important.
Yes, I tried actually.
I used the snippet also with the v1, but it do not compile. If I remember correctly it was missing a file, maybe the interceptor message

The main issue, with the connected event not being raised is not clear.
🥲🥲 oh no.


1. You can access these message objects with JavaObject. This will be simple.
Ouh ok, I’m not experienced with it. But I will try just to learn
 
Upvote 0

Mike1970

Well-Known Member
Licensed User
Longtime User
What I meant was that you try it with v1, though it is less important
I used the snippet also with the v1, but it do not compile.
I confirm that it does not compile with version 1, and throws this error:


B4X:
Organizzazione Librerie.    (0.06s)
    (AndroidX SDK)
Compilazione risorse    (0.19s)
Collegamento risorse    (0.64s)
    build tools: 33.0.0, android jar: android-33
Compilazione del codice debugger.    (5.96s)
Compilazione del codice Java prodotto.    Error
src\b4a\example\b4xmainpage.java:3: error: package io.moquette.interception.messages does not exist
import io.moquette.interception.messages.*;
^
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
1 error
only showing the first 1 errors, of 10 total; use -Xmaxerrs if you would like to see more

javac 14.0.1
 
Upvote 0

teddybear

Well-Known Member
Licensed User
Hi Erel! How are you?

Thank you very much for the answer.
I re-installed the v2* of the mqtt broker, then I added your snippet and unfortuntely, as you said, the events to which I was more interested in does not work 😂 (onConnect and onDisconnect).
I modified the broker V2, the connected and disconnected events can be raised.
 
Upvote 2
Solution

teddybear

Well-Known Member
Licensed User
Good job!

Do you know what was the mistake in my code? Why the events didn't raise?
Yes, I know, it is not the mistake in your code. that is a bug in moquette broker v0.12 (v0.121 fixed). there are no dispatching methods for the 2 events.
I added the methods to the libaray source code. you can find them in MQTTConnection.java and PostOffice.java by searching keyword Teddybear.
 
Last edited:
Upvote 0
Top