Other B4X Push Server

Discussion in 'B4J Libraries & Classes' started by Erel, Dec 24, 2014.

  1. Erel

    Erel Administrator Staff Member Licensed User

    B4X Push Server is a B4J written back-end server for B4i and B4A apps that use push notifications (Android - GCM, iOS - APN).

    Its two main features are:
    - Collect device tokens - DeviceToken class.
    - Send messages to the devices - Send servlet (which calls iOSPush and AndroidPush modules).

    Configuration

    There are several settings which you need to configure. The configuration file is located under the Objects folder:

    [​IMG]

    You must set the following properties:
    iPushKeyStore / iPushKeystorePassword - Path and password of the push keystore created with B4i (see this tutorial: http://www.b4x.com/android/forum/threads/push-notifications.48562/).

    AndroidApiKey - The GCM key from Google developer console (see this tutorial: http://www.b4x.com/android/forum/threads/19226/#content).

    PushServerPassword - This value is required when sending messages.

    B4A / B4i Apps

    The B4A / B4i apps that receive push notifications (client apps) need to register to the push notifications service when they start and send the received token to the B4X push server. You need to configure the push server url in each of the apps.

    For the B4A app you need to set the SenderId and to add the required text to the manifest editor.

    For the B4i app you need to set the #ProvisionFile attribute to point to the push provision profile.

    Server Code

    The server code is quite simple and can be customized as needed. It depends on jNetwork library v1.10+ (for the SSLSocket).
    The tokens are stored in a SQLite database.

    To send a message to all devices (that were updated in the last 3 days) you need to call the Send servlet:
    http://<server url>/send?password=<PushServerPassword>&text=Message to send

    Apple remote notifications documentation: https://developer.apple.com/library...icationsPG/Chapters/CommunicatingWIthAPS.html
    Google GCM documentation: http://developer.android.com/google/gcm/index.html


    V0.96 - Fixes an issue with the feedback timer being disabled.
    V0.95 - It adds support for iOS feedback service. These lines should be added to existing config files:

    #change to: feedback.push.apple.com for production
    iFeedback=feedback.sandbox.push.apple.com
    iFeedbackPort=2196

    The feedback service holds a list of rejected tokens. The server will call it once an hour to find rejected tokens which will then be deleted from the database.

    Note that the feedback service isn't working properly in sandbox mode (the problem is in Apple servers).
     

    Attached Files:

    Last edited: Jan 12, 2016
    eps, MarcB, koaunglay and 9 others like this.
  2. NJDude

    NJDude Expert Licensed User

    I tried the sample on Lollipop and it crashes, this is the log:
    Code:
    ** Activity (main) Create, isFirst = true **


    ** 
    Activity (main) Resume **


    ** 
    Service (pushservice) Create **


    ** 
    Service (pushservice) Start **


    java.lang.IllegalArgumentException: 
    Service Intent must be explicit: Intent { act=com.google.android.c2dm.intent.REGISTER (has extras) }


        at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1674)
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1703)
        at android.app.ContextImpl.startService(ContextImpl.java:1687)
        at android.content.ContextWrapper.startService(ContextWrapper.java:515)
        at anywheresoftware.b4a.keywords.Common.StartService(Common.java:726)
        at anywheresoftware.b4a.samples.push.pushservice._registerdevice(pushservice.java:204)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
        at anywheresoftware.b4a.keywords.Common$5.run(Common.java:962)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
    ~e:    at android.app.ActivityThread.main(ActivityThread.java:5221)


        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.c2dm.intent.REGISTER (has extras) }
        at anywheresoftware.b4a.keywords.Common$5.run(Common.java:965)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
    Caused by: java.lang.RuntimeException: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.c2dm.intent.REGISTER (has extras) }
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:201)
        at anywheresoftware.b4a.keywords.Common$5.run(Common.java:962)
        ... 8 more
    Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.google.android.c2dm.intent.REGISTER (has extras) }
        at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1674)
        at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1703)
        at android.app.ContextImpl.startService(ContextImpl.java:1687)
        at android.content.ContextWrapper.startService(ContextWrapper.java:515)
        at anywheresoftware.b4a.keywords.Common.StartService(Common.java:726)
        at anywheresoftware.b4a.samples.push.pushservice._registerdevice(pushservice.java:204)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at anywheresoftware.b4a.BA.raiseEvent2(BA.java:175)
        ... 9 more
    No problems on KitKat or JellyBean
     
  3. Erel

    Erel Administrator Staff Member Licensed User

    It does work here on Nexus 5 with the latest Lollipop version. Which version are you running?
     
  4. little3399

    little3399 Active Member Licensed User

    Hi , Compile error
     

    Attached Files:

  5. NJDude

    NJDude Expert Licensed User

    Lollipop 5.0, on a Nexus 7 tab.
     
    Last edited: Dec 25, 2014
  6. Erel

    Erel Administrator Staff Member Licensed User

    jWebSocketClient and WebSocketClient libraries should NOT be referenced.

    @NJDude change the RegisterDevice code to:
    Code:
    Sub RegisterDevice (Unregister As Boolean)
       
    Dim i As Intent
       
    If Unregister Then     
         i.Initialize(
    "com.google.android.c2dm.intent.UNREGISTER""")
       
    Else
         i.Initialize(
    "com.google.android.c2dm.intent.REGISTER""")
         i.PutExtra(
    "sender", Main.SenderId)
       
    End If
       
    Dim jo As JavaObject = i
       jo.RunMethod(
    "setPackage"Array("com.google.android.gms"))
       
    Dim r As Reflector
       
    Dim i2 As Intent
       i2 = r.CreateObject(
    "android.content.Intent")
       
    Dim pi As Object
       pi = r.RunStaticMethod(
    "android.app.PendingIntent""getBroadcast", _
         
    Array As Object(r.GetContext, 0, i2, 0), _
         
    Array As String("android.content.Context""java.lang.int""android.content.Intent""java.lang.int"))
       i.PutExtra(
    "app", pi)
       
    StartService(i)
    End Sub
    Does it work?
     
    dealsmonkey, pesquera and dar2o3 like this.
  7. NJDude

    NJDude Expert Licensed User

    Now it's working, thanks.
     
  8. ivanomonti

    ivanomonti Well-Known Member Licensed User

    Compiler error line 19 InitializeSSL module iOSPhus project b4j

    Code:
    Private Sub Connect
        
    If sock.IsInitialized Then sock.Close
        
    Dim sock As Socket
        sock.InitializeSSL(
    "sock"File.OpenInput(Main.config.Get("iPushKeystore"), ""), Main.config.Get("iPushKeystorePassword")) ' ???
        sock.Connect(Main.config.Get("iGateway"), Main.config.Get("iGateWayPort"), 30000)
    End Sub
    Screen Shot 2014-12-26 at 21.15.12.png

    Screen Shot 2014-12-26 at 21.17.05.png
     
  9. DKnowles

    DKnowles Member Licensed User

    Ivan, download the jNetwork library v1.10+ from the top post, under server, I just spent an hour trying to work out what was wrong.

    David
     
    ivanomonti likes this.
  10. ivanomonti

    ivanomonti Well-Known Member Licensed User

    1. stesso problema
    2. same problem

    2015-01-07_115423.jpg
     
  11. Erel

    Erel Administrator Staff Member Licensed User

    Check the library version in the Libraries tab. Make sure to copy the library files to the internal folder (under C:\Program Files).
     
  12. Shay

    Shay Well-Known Member Licensed User

    Where do I get the iPushKeystorePassword
    I don't recall asking & giving any password
     
  13. Erel

    Erel Administrator Staff Member Licensed User

    It is the same password you used when you created the key in the IDE.
     
  14. Shay

    Shay Well-Known Member Licensed User

    I manage to install all, b.t.w my tip is to open incoming port (51044) on firewall
    and on the URL for sending the message you need to add IP: port

    I see that both devices are registered, and once I send message from browser I am getting
    Message sent to 2 device(s).
    and on server:
    "send message to
    Message was sent successfully"
    and nothing arrive to both phones (IOS/Android)
    What am I missing?
     
  15. Shay

    Shay Well-Known Member Licensed User

    I fixed the clock on my server, and not IOS is working
    still Android is not
     
  16. Shay

    Shay Well-Known Member Licensed User

    fixed, matched the project id to SenderID in the b4A project
     
  17. roddy

    roddy Member Licensed User

    B4X-PushServer is server
    B4i-PushClient and B4A-PushClient are Device's APP. Receive messages.

    If the above is correct,and my question is:
    Send a message from there?
    From PC(windows)? Cell phone(iphone or Android)?
    How to do?
     
  18. Erel

    Erel Administrator Staff Member Licensed User

    Correct.

    You can send a message from anywhere you like by sending a http request to the server (see the Server code section in the first post).
     
  19. roddy

    roddy Member Licensed User

    I see. Thank you.
     
  20. DKnowles

    DKnowles Member Licensed User

    UPDATE : Just tried via Mobile Internet (Different IP Address), works fine.
    On further investigation, Cable speed just been upgraded to a nice 150+MBit
    and the lovely VirginMedia IT guys reset my router, inc deleting all the firewall settings.... Added the push Server port back in, and hey presto it works again. 2 hours wasted Grrr

    Push Server Just stopped working? getting 'Remote host closed connection during handshake'.

    This is what is show in the Log, not changed anything since last week?
    This also happened the first time I tried to run so its not like apple think its a DOS attack (or shouldn't) which I see on the web forums as the main thing that rejects the connection.

    Help anyone?
    ps note the warnings and info lines before the 'server is listening on port: 51044' line have always popped up.

    Program started.
    2015-02-09 15:49:19.140:INFO::main: Logging initialized @671ms
    2015-02-09 15:49:19.203:INFO:eek:ejs.Server:main: jetty-9.1.z-SNAPSHOT
    2015-02-09 15:49:19.234:WARN:eek:ejh.MimeTypes:main: java.util.MissingResourceException: Can't find bundle for base name org/eclipse/jetty/http/encoding, locale en_GB
    2015-02-09 15:49:19.234:INFO:eek:ejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@15669ae{/,file:/C:/Users/David%20Knowles/Documents/B4i/PushServer/Objects/www,AVAILABLE}
    2015-02-09 15:49:19.234:INFO:eek:ejs.AbstractNCSARequestLog:main: Opened C:\Users\David Knowles\Documents\B4i\PushServer\Objects\logs\b4j-2015_02_09.request.log
    2015-02-09 15:49:19.250:INFO:eek:ejs.ServerConnector:main: Started ServerConnector@1b2668f{HTTP/1.1}{0.0.0.0:51044}
    2015-02-09 15:49:19.250:INFO:eek:ejs.Server:main: Started @796ms
    Emulated network latency: 100ms
    server version: 0.9
    server is listening on port: 51044
    javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
    at anywheresoftware.b4a.objects.SocketWrapper$1.run(SocketWrapper.java:141)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
    Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(InputRecord.java:482)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
    ... 9 more
    Error connecting socket: (EOFException) java.io.EOFException: SSL peer shut down incorrectly
    Trying to reconnect...
    [/CODE]
     
    Last edited: Feb 9, 2015
Loading...