Other B4X Push Server

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:

SS-2014-12-24_10.56.25.png


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

AndroidApiKey - The GCM key from Google developer console (see this tutorial: https://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).
 

Attachments

  • B4i-PushClient.zip
    3.1 KB · Views: 1,499
  • B4A-PushClient.zip
    7.5 KB · Views: 1,964
  • PushServer.zip
    13.3 KB · Views: 1,539
Last edited:

Shay

Well-Known Member
Licensed User
Longtime User
Here is the full log that I get (while it fails to retry)
java -jar PushServer.jar
2015-02-21 17:34:10.949:INFO::main: Logging initialized @384ms
2015-02-21 17:34:11.066:INFO:eek:ejs.Server:main: jetty-9.1.z-SNAPSHOT
2015-02-21 17:34:11.083:WARN:eek:ejh.MimeTypes:main: java.util.MissingResourceException: Can't find bundle for base name org/eclipse/jetty/http/encoding, locale en_US
2015-02-21 17:34:11.091:INFO:eek:ejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@6b01344f{/,file:/var/www/html/PushServer/www,AVAILABLE}
2015-02-21 17:34:11.094:INFO:eek:ejs.AbstractNCSARequestLog:main: Opened /var/www/html/PushServer/logs/b4j-2015_02_21.request.log
2015-02-21 17:34:11.102:INFO:eek:ejs.ServerConnector:main: Started ServerConnector@46e91e2f{HTTP/1.1}{0.0.0.0:81}
2015-02-21 17:34:11.102:INFO:eek:ejs.Server:main: Started @549ms
server version: 0.19
server is listening on port: 81
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
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:934)
... 9 more
Error connecting socket: (EOFException) java.io.EOFException: SSL peer shut down incorrectly
Trying to reconnect...
java.lang.UnsupportedOperationException: The method shutdownInput() is not supported in SSLSocket
at sun.security.ssl.BaseSSLSocketImpl.shutdownInput(BaseSSLSocketImpl.java:199)
at anywheresoftware.b4a.objects.SocketWrapper.Close(SocketWrapper.java:188)
at b4j.example.iospush._connect(iospush.java:86)
at b4j.example.iospush._timer1_tick(iospush.java:276)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.BA$3.run(BA.java:178)
at anywheresoftware.b4a.keywords.SimpleMessageLoop.runMessageLoop(SimpleMessageLoop.java:30)
at anywheresoftware.b4a.StandardBA.startMessageLoop(StandardBA.java:26)
at anywheresoftware.b4a.keywords.Common.StartMessageLoop(Common.java:131)
at b4j.example.main._appstart(main.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.main(main.java:28)
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
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:934)
... 9 more
Error connecting socket: (EOFException) java.io.EOFException: SSL peer shut down incorrectly
Trying to reconnect...
 

Shay

Well-Known Member
Licensed User
Longtime User
This happens while I start the server, at this point nothing should go from the server
meaning I will send notification only when I get request from someone, and I will send it to specific phones (by type - android or IOS)
(I have query in DB that check if phone is android / ios - db contains both users)
so this part should not be trigger and this point

I can run more debugs, just let me know what to do
 

Shay

Well-Known Member
Licensed User
Longtime User
I don't have network problems
Can you issue some debug version
 

Shay

Well-Known Member
Licensed User
Longtime User
Did not help
ipse/jetty/http/encoding, locale en_US
2015-02-22 19:29:29.527:INFO:eek:ejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@6b01344f{/,file:/var/www/html/PushServer/www,AVAILABLE}
2015-02-22 19:29:29.529:INFO:eek:ejs.AbstractNCSARequestLog:main: Opened /var/www/html/PushServer/logs/b4j-2015_02_22.request.log
2015-02-22 19:29:29.538:INFO:eek:ejs.ServerConnector:main: Started ServerConnector@46e91e2f{HTTP/1.1}{0.0.0.0:81}
2015-02-22 19:29:29.539:INFO:eek:ejs.Server:main: Started @546ms
server version: 0.20
server is listening on port: 81
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
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:934)
... 9 more
Error connecting socket: (EOFException) java.io.EOFException: SSL peer shut down incorrectly
Trying to reconnect...
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:953)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1332)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1359)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1343)
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:934)
... 9 more
Error connecting socket: (EOFException) java.io.EOFException: SSL peer shut down incorrectly
Trying to reconnect...
 

walterf25

Expert
Licensed User
Longtime User
jWebSocketClient and WebSocketClient libraries should NOT be referenced.

@NJDude change the RegisterDevice code to:
B4X:
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?
Hi All, I was wondering if i could get some help from the experts, i'm trying to get this to work, i've added my senderID to the B4A Push Example app, as well as the my laptop's ip address and the listening port.

The push example app seems to work fine but it doesn't seem to register i get this error

token: APA91bF8hvyJ2W-gSx6Rts1tIUxu7w6GAgvTyBmg0AWbURTCr7YzzIr02Ex5Mh72WnigkkjEGUurELM5XCp2Mt6YA6wTWXzyvOdSIf9b8Y-H-uw-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
** Service (httputils2service) Create **
** Service (httputils2service) Start **
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 404 </title>
</head>
<body>
<h2>HTTP ERROR: 404</h2>
<p>Problem accessing //devicetoken. Reason:
<pre> Not Found</pre></p>
<hr /><i><small>Powered by Jetty://</small></i>
</body>
</html>
Error uploading token
** Activity (main) Pause, UserClosed = true **
** Service (pushservice) Destroy **

Any Ideas why I get this, I also placed the api key in the config text file in the B4J project, any suggestions or comments will be helpful.

Thanks all
Walter
 

walterf25

Expert
Licensed User
Longtime User
Hi All, I was wondering if i could get some help from the experts, i'm trying to get this to work, i've added my senderID to the B4A Push Example app, as well as the my laptop's ip address and the listening port.

The push example app seems to work fine but it doesn't seem to register i get this error



Any Ideas why I get this, I also placed the api key in the config text file in the B4J project, any suggestions or comments will be helpful.

Thanks all
Walter
Never mind all i've figured it out, it turns out that there was an extra forward slash in the poststring here

B4X:
Sub HandleRegistrationResult(Intent As Intent)
    If Intent.HasExtra("error") Then
        Log("Error: " & Intent.GetExtra("error"))
        ToastMessageShow("Error: " & Intent.GetExtra("error"), True)
    Else If Intent.HasExtra("registration_id") Then
        Dim token As String = Intent.GetExtra("registration_id")
        Log("token: " & token)
        Dim j As HttpJob
        j.Initialize("j", Me)
        Log("url: " & Main.ServerUrl & "deviceToken")
        Log("token: " & token)
        j.PostString(Main.ServerUrl & "devicetoken", "token=" & token & "&type=2")    
    End If 
End Sub

the variable main.ServerUrl already has a forward slash at the end of it and there was another one added right at "/devicetoken"
so the url was looking like this "url: http://192.xxx.xx.xx:51044//deviceToken" with two forward slashes right after the listening port.

Thanks all
Walter
 

Shay

Well-Known Member
Licensed User
Longtime User
keep testing it, since sometimes it will connect at first try and sometimes after many retry
 

walterf25

Expert
Licensed User
Longtime User
Can the B4J Push Server be run on a host? i would like to move the program from my pc to another place where i can access it from anywhere?

Thanks,
Walter
 

fishwolf

Well-Known Member
Licensed User
Longtime User
I have configure the server for Android and work fine.

Now for Ios, i have create the certificate, copy in Key Folder and run the "Create push keystore", but i have a Error Connection after 10-15 seconds.

What is the problem?

Immagine.jpg


Immagine1.jpg
 
Last edited:

Shay

Well-Known Member
Licensed User
Longtime User
Erel, can you check if you stop the server and start it again (please try this few times)
if you get my errors or not?
also what is java openjdk version that you are using?
 
Top