B4J Question MQTT Retained & QoS

madru

Active Member
Licensed User
Longtime User
any change to get those via _MessageArrived ?

B4X:
finalint qos = mqttMessage.getQos();
finalboolean retained = mqttMessage.isRetained();

THX
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can use a custom callback. Untested code:
B4X:
Dim jo As JavaObject = MqttClient
Dim event As Object = jo.CreateEventFromUI("org.eclipse.paho.client.mqttv3.MqttCallback", "message", Null)
jo.GetFieldJO("client").RunMethod("setCallback", Array(event))
End Sub

Sub Message_Event (MethodName As String, Args() As Object) As Object
 If MethodName = "messageArrived" Then
   Log(Args(0))
   Log(Args(1)) 'This is a MqttMessage. It should be simple to access its properties with JavaObject
 Return Null
End Sub
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
Hi Erel,

can you check if the retained flag is properly set? - right now it is always set to False. It also looks like that the 1st received message after a subscription does not fire the event.
There is the possibility that the retain=false is due to the missing 1st event, but I am nit sure how to verify
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
OK, 'retained variable' got overwritten :(

if somebody is interested how to get the values:
B4X:
Sub Message_Event (MethodName As String, Args() As Object) As Object

    If MethodName = "messageArrived" Then
        Dim mA AsJavaObject
        mA = Args(1)
        Log("QoS: "& mA.RunMethod("getQos",Null))
        Log("Retained Message: "& mA.RunMethod("isRetained",Null))
        Log("Duplicate Message: "& mA.RunMethod("isDuplicate",Null))
        ReturnNull

    EndIf

EndSub

but I am still struggling with the 1st subscription as no event will be fired in that case.

I have the event declaration in _MessageArrived not sure if that is correct.....
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
I am doing something wrong but I can't figure out what :(

with the Message_Event in place I do not receive any events in _MessageArrived anymore.....
 
Upvote 0

rboeck

Well-Known Member
Licensed User
Longtime User
Try to remove Null in the Line Return;
it was my first question, when i see the code. What does isDuplicate mean and in which situtation do you get duplicates?
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
Hi, tried that already with no success.....

The duplicate flag indicates, that this message is a duplicate and is resent because the other end didn’t acknowledge the original message. This is only relevant for QoS greater than 0
For at-least-once service, the sender has to keep a copy of the message until it receives a PUBACK from the receiver. In the absence of a PUBACK, the message must be resent. There are two possible causes for a resend: the original message may indeed not have been received, or the PUBACK may not have been received. In the latter case, the original was received and sent on for processing, but the sender doesn’t know that. So it sends a duplicate, but the receiver will have no record that this is a duplicate message; to it this is simply a new message. So it will process it just as it did the first one.
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
I am lost, can't get it to work properly

_client_MessageArrived does not fire anymore after _Event got called.

B4X:
Sub Process_Globals
Dim jo As JavaObject = mqtt
end sub

Private Sub mqtt_client_MessageArrived (topic As String, Payload() As Byte)

    Dim event AsObject = jo.CreateEventFromUI("org.eclipse.paho.client.mqttv3.MqttCallback", "message", Null)
    jo.GetFieldJO("client").RunMethod("setCallback", Array(event))

'do something with topic & Payload here

end sub

Sub Message_Event (MethodName As String, Args() As Object) As Object

    If MethodName = "messageArrived" Then
        Dim mA AsJavaObject
        mA = Args(1)
        Log("QoS: "& mA.RunMethod("getQos",Null))
        Log("Retained Message: "& mA.RunMethod("isRetained",Null))
        Log("Duplicate Message: "& mA.RunMethod("isDuplicate",Null))
        ReturnNull
    EndIf

EndSub
 
Upvote 0

madru

Active Member
Licensed User
Longtime User
OK, makes sense....

...but how do I initialise jo?
B4X:
182: jo.GetFieldJO("client").RunMethod("setCallback", Array(event))

Error occurred on line: 182 (Main)
java.lang.RuntimeException: Object should first be initialized (JavaObject).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:32)
at anywheresoftware.b4j.object.JavaObject.getCurrentClass(JavaObject.java:258)
at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:118)
at com.vlab.mqtt.test.main._appstart(main.java:298)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:614)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:231)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:159)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:93)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
at com.vlab.mqtt.test.main.start(main.java:38)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$163(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$176(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$174(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$175(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$149(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)
 
Upvote 0

rboeck

Well-Known Member
Licensed User
Longtime User
Are this possibilities useable only for B4J or for all clients?
@madru: Do you have good webinfos with this 'insider' information about mqtt?
 
Upvote 0
Top