B4J Tutorial [Server] Upload files from your B4A app to your B4J server over the internet

Status
Not open for further replies.
This example shows how to make your B4J server application accessible over the internet.

The implemented server is a simple file server that allows you to upload files from your B4A application to the server over the internet.

The following steps are required in order to make your server accessible over the internet:
  1. As the router (or computer) external IP address changes from time to time we need to use a service that maps a known address to our dynamic address. In this case I used a free service named DuckDNS. You should register with them and choose a unique domain for your server.
    They will also provide you with a token. In the Main module we use a timer to call their service (with this token) every 10 minutes. This updates the IP address if needed.
  2. Router setup
    • Port forwarding - Configure the router to forward all incoming requests on the given port to your computer address.
    • Static IP - On some routers port forwarding will only work with a specific local IP address. The solution is to configure the router to always provide your computer with the same address.
    • Search Google for instructions specific to your router.
  3. Firewall - You need to allow incoming connections on the specific port.
Tips:
- There are several points of failures in this configuration. In order to debug it, run the server and call the test handler. Start with calling it from the computer browser (127.0.0.1:54021/test). If there is an error then the server is not running properly.
Now try to call it with duckdns: yourdomain.duckdns.org:54021/test
If it works then the configuration is probably fine. You just need to test it from outside the local network.
If it doesn't work then find your external ip address and try to call it. If it doesn't work with the external ip address then your router is not configured correctly or the firewall is blocking the incoming connection.

- Don't worry. Eventually you will get it working :)

Now for the actual file server. The handler is quite simple. It supports two types of messages: text messages and files. The handler reads the data directly from the request input stream. The type parameter (from the query string) tells it whether to treat the data as a text message or as a file that needs to be saved.

One important point is that we need to call req.InputStream before calling req.GetParameter. Otherwise the complete stream will be internally read as the server looks for the parameter in the request body. This will not happen if we first call req.InputStream.

The Android application is quite simple. It just uses HttpUtils2 to send the file or text message.

upload_2014-1-28_13-9-44.png


In order to run it you need to update the link variable based on your domain name.

This tutorial opens the door to many interesting solutions. You can easily turn any PC into a backend server for your Android applications.
 

Attachments

  • FileClient-B4A.zip
    7.5 KB · Views: 5,032
  • FileServer-B4J.zip
    4.3 KB · Views: 5,342

upsis

Member
Licensed User
Longtime User
What changes should I make to the FileServer-B4j example can be published on my internet service provider? Thanks
 

driesvp

Member
Licensed User
Longtime User
When selecting a photo to upload, quite often the photo isn't uploaded. Sometimes after retrying several times, it works.
I notice in debugger mode that when this happens the screen "Waiting for IDE-debugger to connect" appears. When the photo succesfull uploads, this screen does not appear.

Any idea what causes this?
 

granmaestro

Member
Licensed User
Longtime User
@billzhan layout files created with v3.20 will not work with previous versions.

@derez sure. Create a new Download handler. Open an InputStream and use File.Copy2 to copy it to the response OutputStream.
please,

can you explain this : Create a new Download handler. Open an InputStream and use File.Copy2 to copy it to the response OutputStream.

thank you
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Files stored under the www folder are served automatically. If you want to allow other files to be downloaded then you should use a custom handler.

For example you can use this code to create a handler that sends a file from c:\temp to the client. The file name is passed in the query (www.example.com?file=test1.jpg)
B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
   Dim FileName As String = req.GetParameter("file")
   Dim In As InputStream = File.OpenInput("c:\temp", FileName)
   File.Copy2(In, resp.OutputStream)
End Sub
 

granthierry

Member
Licensed User
Longtime User
Files stored under the www folder are served automatically. If you want to allow other files to be downloaded then you should use a custom handler.

For example you can use this code to create a handler that sends a file from c:\temp to the client. The file name is passed in the query (www.example.com?file=test1.jpg)
B4X:
Sub Handle(req As ServletRequest, resp As ServletResponse)
   Dim FileName As String = req.GetParameter("file")
   Dim In As InputStream = File.OpenInput("c:\temp", FileName)
   File.Copy2(In, resp.OutputStream)
End Sub
Thank you Erel,

If i understand : the server send the file. ( i usually use ftp connection )
And before the client send a request.

I don't know if i can make the request.

Thank you
 

Fabrice La

Active Member
Licensed User
Longtime User
How to use this example in ssl (https://) ? to avoid :

Error: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
 

Fabrice La

Active Member
Licensed User
Longtime User
I know this tutorial for Server.
This error
Error: javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
is from B4A on device try to upload file to ssl server. I am using example "FileClient-B4A" and try to upload to ssl Server.
 

Fabrice La

Active Member
Licensed User
Longtime User
I did add :
B4X:
Dim su As StringUtils
        Dim j As HttpJob
        Dim hc As HttpClient
        hc.InitializeAcceptAll("hclient")
        j.Initialize("file", Me)
        link = link & spbox.SelectedItem & "/"
        j.PostBytes(link & "?type=file&name=" & su.EncodeUrl(FileName, "UTF8"), _
            out.ToBytesArray)

No success
 

LucaMs

Expert
Licensed User
Longtime User
  1. Router setup
    • Port forwarding - Configure the router to forward all incoming requests on the given port to your computer address.
    • Static IP - On some routers port forwarding will only work with a specific local IP address. The solution is to configure the router to always provide your computer with the same address.
    • Search Google for instructions specific to your router.
Tips:
- There are several points of failures in this configuration. In order to debug it, run the server and call the test handler. Start with calling it from the computer browser (127.0.0.1:54021/test). If there is an error then the server is not running properly.
Now try to call it with duckdns: yourdomain.duckdns.org:54021/test

I tried calling 127.0.0.1:54021/test and it seems to work ("Your ip address: 127.0.0.1").

Then (my router's ip): xxx.xxx.xxx.xxx:54021/test - failed.

I have 1 active port forwarding:

Private IP: <MyPC IP - it is fixed>
Protocol Type: TCP
Public Start Port: 54021
Public End Port: 54021
Connection: PVC0

I also tried disabling both the firewalls (router & pc)

In the client code (I get a "connection timeout") i have:
Private link As String = "http://xxx.xxx.xxx.xxx:54021/upload" (xxx... is my router's ip)

Note that ping (from client) responds.
 
Last edited:
Status
Not open for further replies.
Top