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,636
  • DataCollectionDevice.zip
    8 KB · Views: 1,415
  • DataCollectionDesktop.zip
    2.1 KB · Views: 661
Last edited:

delozoya

Member
Licensed User
There is no persistent connection here. It is a standard http server.

ok, but when you spend 10 seconds without connection, then no receipt or sending data. if they are only five seconds, so if you send or receive data.
 

Roberto P.

Well-Known Member
Licensed User
Hi Erel,
I try to run the sample but returns the error of the picture.
HelloWorld example works.
what is wrong?
 

Attachments

  • Error.png
    Error.png
    32.6 KB · Views: 347

billzhan

Active Member
Licensed User
Start the jar with command line, see what' in logs:
B4X:
java -jar DataCollectionServer.jar
 

Roberto P.

Well-Known Member
Licensed User
thanks for reply billzhan
but it still does not work!?!
looks picture.
thank you
 

Attachments

  • error.png
    error.png
    40.1 KB · Views: 307

billzhan

Active Member
Licensed User
I see the jar size is small.So libs are not merged to the jar. #MergeLibraries: True

B4X:
#Region  Project Attributes
   ...
    #MergeLibraries: True
 
#End Region
 

Roberto P.

Well-Known Member
Licensed User
fantastic! works .... thanks a lot.
also can you tell me which jar should I use to connect to a sql db?

P.S. as a system to send data to the server seems slower RemoteDataConnector or am I wrong?
 

Roberto P.

Well-Known Member
Licensed User
excuse me if I make another request!
how do I make me return a field map from the server to update the DB client B4A?
thanks in advance
 

billzhan

Active Member
Licensed User
Not sure that I understand properly.

The demo is based on sqlite, I you want to use other dbs,you can use jsql(download and set up with different jdbc drivers) https://www.b4x.com/android/forum/threads/sql-tutorial.35185/

Note that in this demo, sqlite and threads is set for single thread mode.
B4X:
 srvr.AddHandler("/AddAnimal", "AddAnimal", True)  'True for single thread mode
If you want it work with high concurrent connections see: https://www.b4x.com/android/forum/threads/server-building-web-servers-with-b4j.37172/#content.
Tests show that performance of sqlite (set to Wal mode) will be much more better with SSD . https://www.b4x.com/android/forum/threads/server-performance-measures.37502/
I've not compare it with RDC.

If you want server return a map to client(b4a), you can generate json string of the map, send the json string to client.

B4X:
Public Sub Handle(req As ServletRequest, resp As ServletResponse)
    Dim anml As Animal = Main.ReadObject(req.InputStream)
    Dim m As Map
    m.Initialize
    m.Put("Name", anml.Name)
    m.Put("Age", anml.Age)
    m.Put("Date", DateTime.Date(anml.Date))
    m.Put("Location", anml.Location)
    DBUtils.InsertMaps(Main.SQL1, "Animals", Array As Object(m))
   
   
    Dim resMap As Map=CreateMap("time":DateTime.Now)
    Dim j As JSONGenerator
    j.Initialize(resMap)
    resp.Write(j.ToString)
   
    'resp.Write("Animal added successfully.")
   
   
End Sub


'client parse the returned json string
Sub JobDone(j As HttpJob)
    If j.Success Then
       
        If j.JobName = "yourjobname" Then
            Dim jsonstring As String=j.GetString
            Dim jp As JSONParser
            jp.Initialize(jsonstring)
            ...
        End If
   
    ...
end sub
 

Roberto P.

Well-Known Member
Licensed User
what's the best way to send parameters to the server when sending object?

Sub SendObject (Obj As Object)

raf.WriteObject (Obj, True, 0)
Dim size As Int = raf.CurrentPosition
Dim data (size) As Byte
raf.CurrentPosition = 0
Do While raf.CurrentPosition <size
raf.ReadBytes (date, raf.CurrentPosition, size - raf.CurrentPosition, _
raf.CurrentPosition)
loop
Dim j As HttpJob
j.Initialize ("send object", Me)
j.PostBytes (link & "/ AddAnimal", data)
end Sub
 

Roberto P.

Well-Known Member
Licensed User
is interesting log that records transactions.
Can I add other customized information?
upload_2015-2-9_8-33-25.png
 
Status
Not open for further replies.
Top