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,619
  • B4A-PushClient.zip
    7.5 KB · Views: 2,080
  • PushServer.zip
    13.3 KB · Views: 1,682
Last edited:

moster67

Expert
Licensed User
Longtime User
OMG! I totally forgot about the other two files....

images.jpg

Thanks Erel! Now everything is OK....
 

tufanv

Expert
Licensed User
Longtime User
I want to run 2 different servers on same vps can i use port 51045 for the second one ?
 

shashkiranr

Active Member
Licensed User
Longtime User
Hi All,

I have few doubts,

1. Does the server send messages to google cloud and google cloud send messages to all the registered android devices? If this is true then should the api key obtained from google cloud messaging be server key?

2. How is the flow of messages? from client to server or vice versa.

Kindly let me know.

Best,
SK
 

shashkiranr

Active Member
Licensed User
Longtime User
Thank you for your reply Erel. One question.

If the server has to send specific messages to only a few selected devices then can that be achieved with this? - I got this - I can send a selected list of devices to GCM :)

To test the sever side, should i run the jar in a vps ? or can i run in local host ? or is there any other way test the server side component.


Best,
SK
 
Last edited:

moster67

Expert
Licensed User
Longtime User
Finally I got silent and normal push notifications up and running in a rather reliable way. Now I need to automate certain web calls (send servlets) and execute them according to a schedule. I believe this can be done in 2 ways on the server:

1) Write a script using Cron and/or CronTab to schedule and execute the send servlets (using wget http://localhost:portnumber/....)
2) Add another module in the PushServer using a timer and a query to schedule/execute the send servlets

I would prefer the 2nd option but my timer would probably need to trigger every 60-90 seconds. Would this be too often for the PushServer taking into account it will also likely be receiving data while sending out data?

Any comments/ideas?
 

somed3v3loper

Well-Known Member
Licensed User
Longtime User
My device never receives GCM push .
Registration is successful and B4J server logs and print to html page that message have been sent to device or devices but B4A client does receives nothing .
I even tried the example and changed server ip and sender Id but I never got it working .
Please help
 

moster67

Expert
Licensed User
Longtime User
I read the notes about Apple's feedback-server that it is not reliable in sandbox mode.
In order to check if at least the iOSfeedback code-module is trying to pull data from Apple's server, I put a log statement in the "timer1_tick sub" but it seems it is never executed (should do it every one hour). This should work in sandbox-mode too I guess.
In Main the feedback service is started using "iOSFeedback.Start" and it runs the first time (when server starts) but thereafter the timer does not seem to trigger itself....
Is it working for someone else?

I am also trying this because I want to use the iOSfeedback code-module as an example for creating my own service that sends out notifications automatically (based on a schedule).
 
Last edited:

moster67

Expert
Licensed User
Longtime User
For some reason the timer was disabled in sock_Connected event. Remove that line.
Thanks for sorting it out although I admit I should have seen that line myself.....
 

moster67

Expert
Licensed User
Longtime User
Now the iOSFeedback code module runs with its timer-event - however I noted the following exceptions:

01/12/2016 - 18:10:38 - Connecting to Apple Server to see if there any tokens to delete)
Feedback Socket connected.
Feedback data available
Feedback data available
feedback terminated
01/12/2016 - 18:10:39 - Startup - Connecting to Apple Server to see if there any tokens to delete)
main._appstart (java line: 77)
java.lang.RuntimeException: java.lang.NumberFormatException: empty String
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
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:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.main(main.java:29)
Caused by: java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at b4j.example.iosfeedback._sublisttoarray(iosfeedback.java:158)
at b4j.example.iosfeedback._astream_terminated(iosfeedback.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
... 12 more

main.main (java line: 29)
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.NumberFormatException: empty String
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.example.main.main(main.java:29)
Caused by: java.lang.RuntimeException: java.lang.NumberFormatException: empty String
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:114)
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:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
... 2 more
Caused by: java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at b4j.example.iosfeedback._sublisttoarray(iosfeedback.java:158)
at b4j.example.iosfeedback._astream_terminated(iosfeedback.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:93)
... 12 more

It seems that these exceptions originate from the execution of the iOSFeedback module. After, the server restarts automatically. I note that tokens are received and that GET and POST requests continue to work - the only thing that does not work is the sending out of the notifications. Restarting the server, the sending out of the notification starts working again.

Is this problem related to the problems you mentioned in the first post of this thread when using Apple's Sandbox feedback server (i.e. maybe it is returning "bad" data or tokens not available in my DB and which make the server crash somehow)?

I will leave the server running during the night and see if I get the same exceptions again when the timer in the iOSFeedback module triggers again (maybe it depends also if feedback data is available or not). Will report back tomorrow.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The problem was in Sub SubListToArray. The parameter name was the same as a sub name so it called the sub instead of getting the parameter value.
It should have been a compiler error (it will be in the next version of the IDE).

I've uploaded a new version (0.97) to the first post. It fixes this issue.
I cannot test the feedback here as it doesn't return anything. Please try it and post any issue you encounter.
 

moster67

Expert
Licensed User
Longtime User
OK, I will test later.
I took note of the change of Sub SubListToArray. I was thinking of correcting only this sub in my Pushserver-sources (which I have modified compared to your original version) but I also noted that the OKhttp-library is now required. Did you change any other things? If you don't remember, don't worry - I will use your latest source-code and apply my changes...
 
Top