Android Question MQTT QOS and 'Errors'

RJB

Active Member
Licensed User
Longtime User
Hi,
I've been doing some testing with MQTT between B4R (an 8266) and B4A. The following is what I have found. Can anyone confirm or tell me where I am going wrong?

QOS B4R Client
Subscribe can only set QOS to 0 or 1, not 2
Publish can't be set but defaults to 0. Which means that setting a subscriber to 1 or 2 has no effect, overall the connection will be QOS 0.

QOS B4A Client
Subscribe can be set to 0, 1 or 2
Publish can be set to 0, 1 or 2, but setting it to 1 or 2 will cause a 'Serious error processing...…..' log to be given by the B4A broker. The message still gets through though. Any ideas as to what would cause this?

B4A Broker.
It doesn't seem to be possible to check if the broker is running or to stop it. broker.stop doesn't seem to work and the broker seems to keep running when back or home is pressed - so restarting the broker causes the multiple copies of the messages from the broker.DebugLog even though broker.Stop is used. Example after two back/ restarts:
B4X:
Persistent store file: //moquette_store.mapdb
Persistent store file: //moquette_store.mapdb
Persistent store file: //moquette_store.mapdb
Starting without ACL definition
Starting without ACL definition
Starting without ACL definition
Server binded host: 0.0.0.0, port: 51041
Server binded host: 0.0.0.0, port: 51041
Server binded host: 0.0.0.0, port: 51041
WebSocket is disabled
WebSocket is disabled
WebSocket is disabled
Received a message of type CONNECT
Received a message of type CONNECT
Received a message of type CONNECT
Using ExitApplication in Activity_Pause stops it though!

Stopping/ starting the 8266 end
When the power is removed from the 8266 everything restarts ok, sometimes. Other times it triggers repeated "Serious error processing the message org.eclipse.moquette.proto.messages.PublishMessage@438080e0 for session [clientID: xHub]org.eclipse.moquette.server.netty.NettyChannel@43808290" at the B4A end. Sometimes the messages continue to be sent/ received even though the error is logged, sometimes the messages from the B4A don't get through. Setting the 'keep alive' period shorter mitigates this problem but causes others. Any ideas as to how to avoid this?
Occasionally "An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception" is logged when the 8266 power is removed/ re-applied. Any ideas as to the cause/ solution?

The code I'm using is:
B4X:
B4A Main
Sub Activity_Resume
' If IsPaused(MQTT) = False Then
' StopService(MQTT)
 StartService(MQTT)
End Sub
Sub Activity_Pause (UserClosed As Boolean)
' MQTT.broker.Stop
' MQTT.MQTTClient.close
'StopService(MQTT)

 ExitApplication

End Sub


B4A MQTT service

Sub Process_Globals
 Dim broker As MqttBroker
 Public MQTTClient As MqttClient
 Dim bc As ByteConverter
End Sub

Sub Service_Start (StartingIntent As Intent)

Log("Starting Service")
 broker.Initialize("", 51041) 'first parameter is the event name. It is currently not used.
 broker.DebugLog = True
 broker.start
 MQTTClient.Initialize("MQTTClient", "tcp://127.0.0.1:51041", "Hub1")
 MQTTClient.Connect
End Sub

Sub MQTTClient_Connected(Success As Boolean)
 If Success Then
  Log("client connected to broker")
  Dim B4aClientSubscribeQos As Int = 1
  LogColor(">>>>>>>>Suscribe QOS = " & B4aClientSubscribeQos, Colors.red)
  MQTTClient.Subscribe("Hub", B4aClientSubscribeQos)
 Else
  Log("failed to connect client")
 End If
End Sub
Sub MQTTClient_MessageArrived (Topic As String, Payload() As Byte)
 Try
  If Topic = "Hub" Then
   Log(">>>>>>>>Received: " & bc.StringFromBytes(Payload, "utf8"))
   Dim sendstring As String = "received from Sensor OK"
   Dim B4aPublishQos As Int = 0
   LogColor(">>>>>>>Publish: " & sendstring & " Publish QOS = " & B4aPublishQos, Colors.blue)
   MQTTClient.Publish2("Client", sendstring.GetBytes("utf8"), B4aPublishQos, True)
  End If
 Catch
  Log("M_A: " & LastException)
 End Try
End Sub
Sub Service_Destroy
' MQTTClient.Close
' StopService(Me)
End Sub


B4R/ 8266 code

Sub Process_Globals
 Public Serial1 As Serial
 Dim MQTT As MqttClient
 Public wifi As ESP8266WiFi
 Dim wifiSocket As WiFiSocket
 Dim Timer1 As Timer
End Sub
Private Sub AppStart
 Serial1.Initialize(9600) '115200)
 Delay(5000)
 Log(CRLF, "AppStart")
 Timer1.Initialize("Timer_Tick", 3000)
 If WiFiConnect Then
  Log("Wifi connected")
 Else
  Log("Wifi not connected")
  Return
 End If
 MQTT.Initialize(wifiSocket.Stream, Array As Byte(192,168,1,5), 51041, "Client1", "Mqtt_MessageArrived", "Mqtt_Disconnected")
 MQTTConnect(0)
End Sub
Sub WiFiConnect As Boolean
 If wifi.Connect2("XXXXXXXXX", "YYYYYYYYY") Then
  Return True
 Else
  'wifi.Disconnect
  Return False
 End If
End Sub
Sub MQTTConnect(unused As Byte)
 Dim mo As MqttConnectOptions
 mo.Initialize("","")
 If MQTT.Connect2(mo) = False Then
  Timer1.Enabled = False
  Log("trying to connect to broker")
  CallSubPlus("MQTTConnect", 1000, 0)
  Return
 End If
 Log("Connected to broker")
 MQTT.Subscribe("Client", 1)
 Timer1.Enabled = True
End Sub
Sub Timer_Tick
 Dim Data() As Byte = "Sent from Client1"
 MQTT.Publish2("Hub", Data, True)
 Log("Sent: ", Data)
End Sub
Sub Mqtt_MessageArrived (Topic As String, Payload() As Byte)
 Log("Message arrived. Topic: ", Topic, "; Payload: ", Payload)
End Sub
Sub Mqtt_Disconnected
   Log("Disconnected")
   MQTT.Close
   MQTTConnect(0)
End Sub

Any help, comments, suggestions welcome!
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Subscribe can only set QOS to 0 or 1, not 2
That's true (it is documented in the library documentation).

Publish can be set to 0, 1 or 2, but setting it to 1 or 2 will cause a 'Serious error processing...…..' log to be given by the B4A broker. The message still gets through though. Any ideas as to what would cause this?
This happens in the underlying broker implementation. You should ignore it.

The activity life cycle will not affect the broker. Calling Stop should stop the broker. You can use a process global variable to track the broker state. It will be running until you call Stop. It is best to let it run until the process is killed.
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
Thanks.
I'm still confused as to why I get the multiple messages in the log when stopping/ starting the B4A App?
Other than that I think the biggest problems to producing a reliable App are:
1) The B4R/ 8266 always publishing at QOS 0. Is that the case? Is it possible to change it?
2) Power off/ on at the 8266s leaving the system in an unknown state (working OK/ 8266 not receiving messages/ "An exceptionCaught() event was fired, ….." logs). Restarting the B4A end seems to be the only solution to that. Any ideas as to how to avoid/ detect/ reset it?
Thanks
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I'm still confused as to why I get the multiple messages in the log when stopping/ starting the B4A App?
We cannot debug your code, however you shouldn't stop and start the broker. Start it once and let it run.

The B4R/ 8266 always publishing at QOS 0. Is that the case? Is it possible to change it?
Check the documentation.

Power off/ on at the 8266s leaving the system in an unknown state (working OK/ 8266 not receiving messages/ "An exceptionCaught() event was fired, ….." logs). Restarting the B4A end seems to be the only solution to that. Any ideas as to how to avoid/ detect/ reset it?
Try to change the ESP8266 client id each connection. Rapid connections with the same client id might cause problems. The broker itself is a "black box". There isn't anything that you can do to change its behavior.
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
I've put workarounds in place for the broker and power off issues.
re. B4R publish QOS, the only documentation I can find confirms that the QOS is set to 0.
So the question is still 'Is it possible to change it'? Without that it will be necessary to implement 'send/ confirm/ resend' above MQTT which seems crazy!
 
Upvote 0

RJB

Active Member
Licensed User
Longtime User
OK thanks, it's been interesting to learn about MQTT but ultimately a waste of time for this project as I may as well use Astreams or UDP if I've got to handle QOS myself.
Quotes from https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels/:
"QoS level 0 is often called “fire and forget” and provides the same guarantee as the underlying TCP protocol" and "Use QoS 0 when …You have a completely or mostly stable connection between sender and receiver. A classic use case for QoS 0 is connecting a test client or a front end application to an MQTT broker over a wired connection".
Will B4R be upgraded to include QOS 1 or 2 at some time in the future?
Thanks again for your help.
 
Upvote 0
Top