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: 4,315
  • FileServer-B4J.zip
    4.3 KB · Views: 4,592

LucaMs

Expert
Licensed User
Longtime User
I had forgotten to disable the Windows firewall.

But now instead of getting the "timeout" I get the "refused"
 

LucaMs

Expert
Licensed User
Longtime User
Hard to say. Something is misconfigured in your network configuration.

Yes, I understand that it is impossible for you to help me in this case.

However, I receive an error warning message from the server B4j. However, it responds using 127...

2014-07-24 07:39:12.578:WARN:eek:ejh.MimeTypes:main: java.util.MissingResourceException: Can't find bundle for base name org/eclipse/jetty/http/encoding, locale it_IT

 

LucaMs

Expert
Licensed User
Longtime User
Port problem still not resolved.

Moreover, it seems that to get closer to the port I am forced to disable the router's firewall!
 

LucaMs

Expert
Licensed User
Longtime User
Dear Maxware was able to access my server from his browser.
But I misunderstood or should even I be able to do it from my browser (even if the server is running on my pc)?
 

LucaMs

Expert
Licensed User
Longtime User
You should be able to access your local server from the browser. Start with 127.0.0.1. If it works then try your external ip address. If it doesn't work then your router / firewall are misconfigured.


Yes, these are the steps that you wrote in the first post and I have tried.

So, I have successfully used 127.0.0.1 (localhost) but it does not work using the WAN address of the router, even though the port is open and calls directed to this port are sent to the computer which the server is installed and despite outside of my local network it is accessible.

However, I solve using the fixed address of the server pc for my tests (from mobile clients).

Thanks Erel
 

Giacomo Cuciniello

Member
Licensed User
Longtime User
there is a way to use variables or function declared in Main (in fileserver program) in the "class module" "Upload"?
it seem to see only variables declared in in class module.
Thanks for help
 

LucaMs

Expert
Licensed User
Longtime User
If I understood well (better in Italian :)) you want to call Main's routines from the Upload class?

If so, it probably is not the best choice. Equally probably... just try it ;) (it should be possible, i'll try it soon. Surely it is possible using CallSubDelayed)


[P.S. Tried. It's possible]
 
Last edited:

Giacomo Cuciniello

Member
Licensed User
Longtime User
thank you for your quick answer.
I need to read the value of a variable that is modified in the main inside the handler module so that I can send this value to the client.
(devo vedere il valore di una variabile del main per inviarlo al client tramite l'handler ma l'handler vedere solo le variabili locali e non ha accesso alle variabili del main).(callsubdelayed mi consente di ricevere il risultato della sub?)
I hope it is more clear now.
thanks for your help
 

LucaMs

Expert
Licensed User
Longtime User
You could declare the variable as public global in the main or call a function of the main and get the result.

Puoi semplilcemente dichiara una variabile pubblica globale nel Main e leggerla da qualunque altro modulo oppure richiarmare una funzione scritta nel Main (senza usare CallSubDelayed, semplicemente il nome della funzione).
 

Giacomo Cuciniello

Member
Licensed User
Longtime User
I already tried this way but the editor and the compiler don't recognize the variable in the module.
I think that I solved using "Main." before variable name.
(Sero di aver risolto aggiungendo Main. prima del nome della variabile nel modulo handler, lo sto testando)
Thanks
 

LucaMs

Expert
Licensed User
Longtime User
I already tried this way but the editor and the compiler don't recognize the variable in the module.
I think that I solved using "Main." before variable name.
(Sero di aver risolto aggiungendo Main. prima del nome della variabile nel modulo handler, lo sto testando)
Thanks

That's right. I did not think to write it.

Esatto. Non ho pensato a scriverlo :)
 
Status
Not open for further replies.
Top