Android Tutorial [B4X] MQTT Chat Room

Discussion in 'Tutorials & Examples' started by Erel, Dec 21, 2015.

  1. Erel

    Erel Administrator Staff Member Licensed User

    It's time to learn how to use MQTT: http://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

    [​IMG]

    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: http://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/
     

    Attached Files:

    Last edited: Jan 30, 2017
  2. Douglas Farias

    Douglas Farias Expert Licensed User

    lol this is very nice
     
    Rockefeller Goldman likes this.
  3. MarcoRome

    MarcoRome Expert Licensed User

    Finally. Great work Erel
     
    Rockefeller Goldman likes this.
  4. ilan

    ilan Expert Licensed User

    does it work only on same network? or can i connect my devices also via 3g?
     
  5. Erel

    Erel Administrator Staff Member Licensed User

    You can easily run it over the internet. Use CloudMqtt (or a similar service) instead of the local broker.
     
  6. MarcoRome

    MarcoRome Expert Licensed User

    Hi Erel. It is possible a example ?
     
  7. rwblinn

    rwblinn Well-Known Member Licensed User

    Thanks a Lot - Highly Appreciated to see MQTT evolving with B4X.

    For those interested, have started in the meantime to build some IoT MQTT Experiments - B4J Open Source of course.
     
    Rockefeller Goldman likes this.
  8. MarcoRome

    MarcoRome Expert Licensed User

    I'm trying to make a connection Internet using the service cloudmqtt.com

    Screenshot 2015-12-21 18.56.23.png

    So after registrared and watched the documentation, i tried the same server access in B4A.

    Screenshot 2015-12-21 18.59.10.png

    i read this:
    i have this code:

    Code:
    ....
    client.Initialize(
    "client"$"mqtt://${Name}:${pw}@${Host}:${port}"$"android" & Rnd(110000000))
    ......
    Code complete:

    Code:
    Public Sub ConnectTo(Host As String, Name As String)
        currentName = Name
        isServer = Host = 
    "127.0.0.1" 'Local
        If isServer Then
            
    If brokerStarted = False Then
                broker.Start
                brokerStarted = 
    True
            
    End If
            users.Clear
            Host = 
    "127.0.0.1" 'Locale
        End If
        
    If connected Then client.Close
        
    Dim pw As String = "F03GRGqVzsWf"
        
    'client.Initialize("client", $"tcp://${Host}:${port}"$, "android" & Rnd(1, 10000000)) 'Local
        client.Initialize("client"$"mqtt://${Name}:${pw}@${Host}:${port}"$"android" & Rnd(110000000))
        
    Dim mo As MqttConnectOptions
        mo.Initialize(
    """")
        
    'this message will be sent if the client is disconnected unexpectedly.
        mo.SetLastWill("all/disconnect", serializator.ConvertObjectToBytes(currentName), 0False)
        client.Connect2(mo)
    End Sub
    When i try connect my devices in internet i have this error:

    Screenshot 2015-12-21 19.04.09.png

    Log:

    Where i wrong ??
    Thank you
    Marco
     
    calsdn likes this.
  9. Erel

    Erel Administrator Staff Member Licensed User

    The correct way to connect to MqttCloud is:
    Code:
    client.Initialize("client""tcp://m11.cloudmqtt.com:99999", ...)
    Dim mo As MqttConnectOptions
    mo.Initialize(username, password)
    client.Connect2(mo)
     
  10. Erel

    Erel Administrator Staff Member Licensed User

    valentino s and MarcoRome like this.
  11. aidymp

    aidymp Active Member Licensed User

    is this only for the latest version of B4A? i dont have the money to upgrade yet hopefully Santa will sort that out? i belive my randomaccessfile lib is out of date!

    [​IMG]
     
  12. MarcoRome

    MarcoRome Expert Licensed User

    Strain that dont work about 5.20 but anyway
    this is the best gift that you can do :) "B4X is the best gift"
     
  13. Erel

    Erel Administrator Staff Member Licensed User

  14. javiers

    javiers Active Member Licensed User

    Error connecting ... Android


    Code:
    Copying updated assets files (1)
    ** 
    Service (starter) Create **
    ** 
    Service (starter) Start **
    ** 
    Activity (main) Create, isFirst = true **
    ** 
    Activity (main) Resume **
    ** 
    Activity (main) Pause, UserClosed = false **
    ** 
    Activity (main) Create, isFirst = false **
    ** 
    Activity (main) Resume **
    ** 
    Activity (main) Pause, UserClosed = false **
    ** 
    Activity (main) Create, isFirst = false **
    ** 
    Activity (main) Resume **
    Error occurred on line: 
    33 (Starter)
    java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.keywords.Common.CallSubDebug3(Common.java:
    862)
        at b4a.example.main._btnconnect_click(main.java:
    444)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.shell.Shell.runMethod(
    Shell.java:697)
        at anywheresoftware.b4a.shell.Shell.raiseEventImpl(
    Shell.java:339)
        at anywheresoftware.b4a.shell.Shell.raiseEvent(
    Shell.java:246)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    134)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:
    157)
        at anywheresoftware.b4a.BA.raiseEvent(BA.java:
    153)
        at anywheresoftware.b4a.objects.ViewWrapper$
    1.onClick(ViewWrapper.java:78)
        at android.view.View.performClick(
    View.java:4211)
        at android.view.View$PerformClick.run(
    View.java:17446)
        at android.os.Handler.handleCallback(Handler.java:
    725)
        at android.os.Handler.dispatchMessage(Handler.java:
    92)
        at android.os.Looper.loop(Looper.java:
    153)
        at android.app.ActivityThread.main(ActivityThread.java:
    5297)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
    833)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
    600)
        at dalvik.system.NativeStart.main(Native Method)
    Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
        at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:
    336)
        at anywheresoftware.b4a.debug.Debug.CallSubNew3(Debug.java:
    288)
        ... 
    26 more
    Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:
    318)
        ... 
    27 more
    Caused by: java.lang.RuntimeException: java.lang.ExceptionInInitializerError
        at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    165)
        at anywheresoftware.b4a.debug.Debug.delegate(Debug.java:
    262)
        at b4a.example.starter._connectto(starter.java:
    130)
        ... 
    30 more
    Caused by: java.lang.ExceptionInInitializerError
        at com.lmax.disruptor.RingBufferFields.<clinit>(RingBuffer.java:
    34)
        at com.lmax.disruptor.dsl.Disruptor.<init>(Disruptor.java:
    80)
        at org.eclipse.moquette.spi.impl.SimpleMessaging.init(SimpleMessaging.java:
    99)
        at org.eclipse.moquette.server.Server.startServer(
    Server.java:93)
        at anywheresoftware.b4j.objects.MqttBroker.Start(MqttBroker.java:
    71)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.shell.Shell.runVoidMethod(
    Shell.java:742)
        at anywheresoftware.b4a.shell.Shell.raiseEventImpl(
    Shell.java:342)
        at anywheresoftware.b4a.shell.Shell.raiseEvent(
    Shell.java:246)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:
    511)
        at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:
    134)
        ... 
    32 more
    Caused by: java.lang.RuntimeException: Unable 
    to load unsafe
        at com.lmax.disruptor.util.Util.<clinit>(Util.java:
    112)
        ... 
    45 more
    Caused by: java.security.PrivilegedActionException: java.lang.NoSuchFieldException: theUnsafe
        at java.security.AccessController.doPrivileged(AccessController.java:
    64)
        at com.lmax.disruptor.util.Util.<clinit>(Util.java:
    108)
        ... 
    45 more
    Caused by: java.lang.NoSuchFieldException: theUnsafe
        at java.lang.Class.getDeclaredField(Class.java:
    631)
        at com.lmax.disruptor.util.Util$
    1.run(Util.java:102)
        at com.lmax.disruptor.util.Util$
    1.run(Util.java:99)
        at java.security.AccessController.doPrivileged(AccessController.java:
    60)
        ... 
    46 mo
    Message longer than 
    Log limit (4000). Message was truncated.
    An error occurred:
    (Line: 
    34) brokerStarted = True
    java.lang.RuntimeException: 
    Array not expected...
     
  15. Erel

    Erel Administrator Staff Member Licensed User

  16. javiers

    javiers Active Member Licensed User


    Hello Erel, I have version 4.2.1 on the phone . I try now with the new jar.

    Indeed, now it works with the new jar.

    Another question in the broker installed on Android, what is the IP address to be put ?. The internal IP? Can the app to know what is and put it at the beginning of the service? Thanks for your answers.
     
    Last edited: Dec 28, 2015
  17. Erel

    Erel Administrator Staff Member Licensed User

    It doesn't matter. You can leave it empty.

    Check the code:
    Code:
    Dim host As String = txtHost.Text
    If rdbServer.Checked Then host = "127.0.0.1"
    CallSub3(Starter, "ConnectTo", host, txtName.Text)
     
  18. javiers

    javiers Active Member Licensed User

    Tanks!
     
  19. prajinpraveen

    prajinpraveen Member Licensed User

    Thank you for this tool.

    is it possible to chat with individual users?
     
  20. Erel

    Erel Administrator Staff Member Licensed User

    Yes. You will need to modify the code, but it is quite simple.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice