B4J Tutorial [Web][BANanoMQTT] Send, Receive Push Notifications in your Local Mosquito Broker in your WebApp.

Hi Fam

Well, here it is..

Why?

I need a way to receive MQTT push notifications on my webapp. I didnt want to use Firebase but MQTT. The problem is the B4x Broker does not support websockets, so one can use something else and I didnt want an online broker either, but something I can have control over.

Windows Install

1. Install Mosquitto locally in your server machine. By default this works on port 1833

Setup MQTT broker to work with WebApps i.e. enable websockets

2. Enable Mosquito to send / receive messages via websockets. This enabled your web app to access the messages

Update the conf file of mosquitto, you might find it under program files/mosquito

B4X:
listener 9001
protocol websockets

As I am new to this, I also had to set this

B4X:
allow_anonymous true

For the MQTTX app to be connected and run tests.

If you have installed this as a service, you will need to stop it, update the file and then restart the service.

Set this to your port you want and open it on your firewall. Run your MQTT broker.

3. You will need a toolbox to test your MQTT installation etc. I used MQTTX

For more learning materials on MQTT, you can see these guides
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
BANano Code

1. Have the IP of your machine in hand
2. Have the Port your MQTT is running
3. You can have the username and password also

B4X:
'Static code module
Sub Process_Globals
    Private mqtt As BANanoMQTTClient
End Sub

Sub Initialize
    mqtt.Initialize("mqtt", "xxx.xx.xxx.xx",9001, "/mqtt", False, "clientid")
    Dim ops As BANanoMQTTConnectOptions
    ops.Initialize("username", "password")
    ops.CleanSession = False
    mqtt.Connect2(ops)
End Sub

Sub mqtt_Connected (Success As Boolean)
    If Success Then
        Log("connected " & Success)
        mqtt.Subscribe("incoming", 0)
    Else
        Log(LastException)
        Log("Could not connect to MQTT broker!")
    End If   
End Sub

Private Sub mqtt_Disconnected
    Log("Disconnected")
End Sub

Private Sub mqtt_MessageArrived (Topic As String, Payload() As Byte)
    Log("mqtt_MessageArrived")
    Log(Topic)
    Dim msg As String = BytesToString(Payload, 0, Payload.Length, "utf8")
    Log(msg)
End Sub

Update:

B4X:
Sub MQTTPublish(topic As String, msg As String)
    Try
        If MQTTConnected = False Then StartMQTT
'        Log($"Client: Published to MQTT clients: ${topic} - ${msg}"$)
        mqtt.Publish(topic, msg.GetBytes("UTF-8"))
    Catch
    End Try            'ignore    
End Sub
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
The need for more functions on the MQTT client...

I might as well visit the functionalities discussed here as I forsee another need for them

 

Mashiane

Expert
Licensed User
Longtime User
B4x Code

If you are running this from a b4x app, you can use the code by Erel from here


Remember, to change this code to be

From
B4X:
mqtt.Initialize("mqtt", "ssl://io.adafruit.com:8883", "B4X" & Rnd(0, 999999999))

B4X:
mqtt.Initialize("mqtt", "ws://IP_ADDRESS_OF_SERVER:9001", "B4X" & Rnd(0, 999999999))
 

MichalK73

Well-Known Member
Licensed User
Longtime User
Ok somehow I solved the problem. I created a JS byte.js and put it in the scripts directory.
byte.js:
function stringToBytes(inputString) {
  const encoder = new TextEncoder(); // UTF-8 encoder
  return encoder.encode(inputString); // Zwraca Uint8Array
}

Next load JS is main.bas
B4X:
    BANano.Header.AddJavascriptFile("byte.js")

And execute send message to topic mqtt
B4X:
Private Sub btn1_Click (e As BANanoEvent)
    Dim b1() As Byte = banano.RunJavascriptMethod("stringToBytes",Array As String("Hello my word !!"))
    mqtt.Publish("test/topic", b1)
End Sub

Working :)
 

Mashiane

Expert
Licensed User
Longtime User
ws:// is a non-encrypted protocol
how to set the server to SSL with wss://??
To use wss, the variable should be true

B4X:
mqtt.Initialize("mqtt", "xxx.xx.xxx.xx",9001, "/mqtt", False, "clientid")

Internally, the paho inside the bananocore.js that gets generated injects wss infront of your address it seems.
 

Mashiane

Expert
Licensed User
Longtime User
Ok somehow I solved the problem. I created a JS byte.js and put it in the scripts directory.
byte.js:
function stringToBytes(inputString) {
  const encoder = new TextEncoder(); // UTF-8 encoder
  return encoder.encode(inputString); // Zwraca Uint8Array
}

Next load JS is main.bas
B4X:
    BANano.Header.AddJavascriptFile("byte.js")

And execute send message to topic mqtt
B4X:
Private Sub btn1_Click (e As BANanoEvent)
    Dim b1() As Byte = banano.RunJavascriptMethod("stringToBytes",Array As String("Hello my word !!"))
    mqtt.Publish("test/topic", b1)
End Sub

Working :)
This is what I use

B4X:
Sub MQTTPublish(topic As String, msg As String)
    Try
        If MQTTConnected = False Then StartMQTT
'        Log($"Client: Published to MQTT clients: ${topic} - ${msg}"$)
        mqtt.Publish(topic, msg.GetBytes("UTF-8"))
    Catch
    End Try            'ignore   
End Sub

#Thanks, updated #2 to include the publish sub.
 
Top