B4J Tutorial [Server] Data Collection Solution - Device, Desktop and Web reports

Status
Not open for further replies.
This is an example of building a data collection solution. The solution is made of three components:
- (B4J) Server - Manages the data in a SQLite database.
- (B4A) Device client and (B4J) desktop client - Send new data to the server and show reports.

Note that you can also see the reports from any browser.

In this example we want to track animals. The following type is declared in all three projects:
B4X:
Type Animal (Name As String, Age As Double, Location As String, Date As Long)

upload_2014-1-29_16-0-32.png
upload_2014-1-29_16-1-10.png


Animal objects are sent to the server. This is done with RandomAccessFile as explained here:
Send and receive objects

Both the server and the clients are pretty simple (check the code!).
As we are using SQLite database we set the handlers to be single threaded and thus avoid issues with concurrent transactions.

You can make the server accessible over the internet by following the steps described here:
Upload files from your B4A app to your B4J server over the internet

If you run it in the local network then you only need to open the firewall port (51042 in this example) to incoming connections.
 

Attachments

  • DataCollectionServer.zip
    4.7 KB · Views: 1,952
  • DataCollectionDevice.zip
    8 KB · Views: 1,709
  • DataCollectionDesktop.zip
    2.1 KB · Views: 964
Last edited:

JOTHA

Well-Known Member
Licensed User
Longtime User
I did everything described above and also told the firewall to open the port 51042, but it doesn't work. Here is the message:
Program started.
org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.0.100:51042 refused
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:159)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:576)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:554)
at anywheresoftware.b4a.http.HttpClientWrapper.executeWithTimeout(HttpClientWrapper.java:310)
at anywheresoftware.b4a.http.HttpClientWrapper.access$0(HttpClientWrapper.java:308)
at anywheresoftware.b4a.http.HttpClientWrapper$ExecuteHelper.run(HttpClientWrapper.java:207)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
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:722)
Error: org.apache.http.conn.HttpHostConnectException: Connection to http://192.168.0.100:51042 refused
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:123)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:133)
... 15 more
Connection to http://192.168.0.100:51042 refused
I'm confused.
 

JOTHA

Well-Known Member
Licensed User
Longtime User
Done.
Thank you Erel!
 

sap

Member
Licensed User
Longtime User
hello Erel
the example works well is to select a command line in the webview to simply remove and empty the database you is it possible to support me

thank you
 

sap

Member
Licensed User
Longtime User
[Quote = "Erel, poste: 231375, membre: 1"]. Vous pouvez ajouter un nouveau gestionnaire dans le projet de serveur qui supprime les données dont vous avez besoin [/ quote]


hello
exist there examples because my project is to add functions in DataCollectionDesktop (delete, Were)
 

sap

Member
Licensed User
Longtime User
[Quote = "Erel, poste: 231693, membre: 1"] Dans cet exemple, les données ne sont pas stockées dans le bureau. Elle est stockée dans le serveur. Cela signifie que vous aurez besoin d'envoyer une commande avec HttpUtils2 au serveur qui sera ensuite supprimer les données. [/ Quote]


Merci Erel
 

sap

Member
Licensed User
Longtime User
t [quote = "Erel, poste: 231693, membre: 1"] Dans cet exemple, les données ne sont pas stockées dans le bureau. Elle est stockée dans le serveur. Cela signifie que vous aurez besoin d'envoyer une commande wi h HttpUtils2 au serveur qui sera ensuite supprimer les données. [/ quote]


Mobile I wanted to send to the server located on the local network pc in an application to retrieve the desired data (=?) on my mobile

is it possible to have an example

thank you
 

masmukti

Member
Licensed User
Longtime User
hello Erel. I am new here, how to display images from SQL BLOB to HTML in an application server?
Untitled.png
 

delozoya

Member
Licensed User
Longtime User
Hello. apart the view the database in webview in app Desktop. I can send the database in server to Desktop?
 

luke2012

Well-Known Member
Licensed User
Longtime User
Hi @Erel,
I need to retreive a record passing the record ID in order to retreive the related name (I have an ID and Name fields).
So I have to create an handler (like /report example) in order to retreive the requested data.

In the example (/report handler) the caller job doesn't pass any parameter (request) and the handler execute a "select * ..." query in order to retreive the data.

My target is to pass a parameter (ID) to the request in order to execute a query using the id as where condition.
How do this using http job object ?
 

luke2012

Well-Known Member
Licensed User
Longtime User
Passing "GET" parameters is very simple.

You add the parameters to the link:
http://example.com/report?key1=value1&key2=value2

In the server you can get the parameters with:
B4X:
req.GetParameter("key1")
Note that it is better to use HttpJob.Download2 to build the link.

@Erel first of all, thanks for your fast and useful reply!
Another little question :)

Within the the class handler, how I can manage the SQLite constraints violations (ex. unique constraint raised by the db engine) in order to advice the user and handle the event in the client (app) ?
 
Status
Not open for further replies.
Top