Android Tutorial [B4X] MQTT Chat Room

It's time to learn how to use MQTT: https://www.b4x.com/android/forum/threads/59471/#content
It is simple and powerful. In most cases MQTT is the best solution for low level networks. Low level network means a network solution that is traditionally based on ServerSocket + Socket + AsyncStreams.

In this example we implement a chat room with one or more users. The MQTT broker is embedded in the Android app (jMqttBroker library). The clients are Android, iOS or desktop apps. Any number of users can join.


upload_2015-12-21_14-42-4.png
upload_2015-12-21_14-43-50.png


SS-2015-12-21_14.40.07.png


When you start the Android app you can choose whether it will be the server. The other clients will connect to the server.

The messages are serialized with B4XSerializator (RandomAccessFile library). B4XSerializator is very useful for cross platform communication.

Users can join and leave the chat room. The list of users will be updated automatically.
Note the usage of the LastWill feature. When a client is disconnected unexpectedly (and only if it is unexpectedly) the LastWill message will be sent. This allows us to remove the client from the list.

The UI state is managed by StateManager (in B4A and B4i).
It is a simple and flexible UI implemented with anchors. Note that it properly handles the soft keyboard changes.

jMQTT library: https://www.b4x.com/android/forum/threads/59472/#content
jMqttBroker: https://www.b4x.com/android/forum/threads/mqttbroker.61548

Extension to this example with auto discovery: https://www.b4x.com/android/forum/posts/480542/
 

Attachments

  • Chat_B4i.zip
    6.1 KB · Views: 1,556
  • Chat_B4J.zip
    3.8 KB · Views: 2,563
  • Chat_B4A.zip
    11.3 KB · Views: 1,265
Last edited:

archeus

Member
Licensed User
I was testing this code with CloudMQTT.

No problem to make it work, change the code to use it just like a client.

But if I use let's say MqttFX (MQTT client in Java) or MyMQTT and connect it to my CloudMQTT account (I use another credential than the one use in my Android App).

Each time MqttFX send message, My Android App crash. And all message sent by my app are unreadeable by MyMQTT or MqttFX.
If I deploy my app on 2 different android device, they are perfectly able to communicate, no crash. MyMQTT and MqttFX are perfectly able to communicate each other.

Problem seems to be here (in Starter)

B4X:
Private Sub client_MessageArrived (Topic As String, Payload() As Byte)
    Dim receivedObject As Object = serializator.ConvertBytesToObject(Payload)

I saw on some MQTT docs that Payload are Byte.

I try to log Payload to see the data but crash (i'm a B4a newbie btw).

Is this code use a different format than the one usually use by other software to send data ? How can I convert text coming from traditional mqtt software to be readable by the App ?

Thanks for help
 

MolsonB

Member
Licensed User
In the B4A program, the Sub "Disconnect" in the Starter service module is missing the publish disconnect command.

B4X:
Public Sub Disconnect
    If connected Then
        connected = False
        client.Publish2("all/disconnect", serializator.ConvertObjectToBytes(currentName), 0, False)
        client.Close
    End If
End Sub
 

Gandalf

Member
Licensed User
In the B4A program, the Sub "Disconnect" in the Starter service module is missing the publish disconnect command.

You are correct. LastWill message will only be published in case of unexpected disconnect. If you do disconnect with Client.Close, you need to publish disconnect message manually before closing client. Making LastWill and Disconnect messages different allows differentiating unexpected disconnects from intended and properly indicating them on server side.
 

ValhallSW

Member
Licensed User
I have tried this before: To make the PC/B4J as server. I love the example in the first post, but I have huge problem making B4J as server. I have tried what Erel told me, but when I connect to 127.0.0.1 it crashed/stopped. I feel like I've tried a lot of configurations. With no luck.

So:

Are there anyone that can help me to get the PC/B4J to work as the server in this example? PLEASE
 

luke2012

Well-Known Member
Licensed User
Hi,
MQTT Chat could be implemented also within the same network where I have implemented CloudKVS server?
 

cxdzbl

Active Member
Licensed User
It's time to learn how to use MQTT: https://www.b4x.com/android/forum/threads/59471/#content
It is simple and powerful. In most cases MQTT is the best solution for low level networks. Low level network means a network solution that is traditionally based on ServerSocket + Socket + AsyncStreams.

In this example we implement a chat room with one or more users. The MQTT broker is embedded in the Android app (jMqttBroker library). The clients are Android, iOS or desktop apps. Any number of users can join.


View attachment 39859 View attachment 39863

SS-2015-12-21_14.40.07.png


When you start the Android app you can choose whether it will be the server. The other clients will connect to the server.

The messages are serialized with B4XSerializator (RandomAccessFile library). B4XSerializator is very useful for cross platform communication.

Users can join and leave the chat room. The list of users will be updated automatically.
Note the usage of the LastWill feature. When a client is disconnected unexpectedly (and only if it is unexpectedly) the LastWill message will be sent. This allows us to remove the client from the list.

The UI state is managed by StateManager (in B4A and B4i).
It is a simple and flexible UI implemented with anchors. Note that it properly handles the soft keyboard changes.

jMQTT library: https://www.b4x.com/android/forum/threads/59472/#content
jMqttBroker: https://www.b4x.com/android/forum/threads/mqttbroker.61548

Extension to this example with auto discovery: https://www.b4x.com/android/forum/posts/480542/
Subscription: client.Subscribe ("all/#", 2)
Send: client.Publish2 ("all/ycwx", serializator.ConvertObjectToBytes (), 2, true)
When the client is online, the messages can receive messages. After shutdown, the messages sent by other clients can not be received. (I don't use the Mqttbroker library.) what's wrong with me?
 

cxdzbl

Active Member
Licensed User
If you dont use the MqttBroker library then this thread is probably the wrong place for your question as this thread is about MqTT chatroom
I found it wasn't MqttBroker's problem:
1, each client clinetID must be fixed and unique.
2, to CleanSession=False. Ensure persistence
3, Subscribe ("all/#", 0) cannot repeat the subscription, or an unknown error will occur.
Thank you, donmanfred. I don't know how to make sure the client has subscribed yet.
 
Top