Linchenyu / webiopi

Automatically exported from code.google.com/p/webiopi
0 stars 0 forks source link

Java (partly Python) client improvement possibilities #44

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Add parameter configuration possibilities to HttpURLConnection:

// Timing parameters
urlConnection.setReadTimeout(...);
urlConnection.setConnectTimeout(...);

// Sometimes needed for POST, some HTTP servers complain if nothing is 
// posted (like webiopi does) but content-type is unset
urlConnection.setRequestProperty("Content-Type", "text/plain");

// Avoid zipping  
urlConnection.setRequestProperty("Accept-Encoding", "identity");

// Cache management
urlConnection.setUseCaches(false);

Add HTTP (and maybe CoAP) response handling management possibilities:

// Error handling
urlConnection.getResponseCode();
urlConnection.getResponseMessage();
// allow direct JSON response switching by detecting response mime type
urlConnection.getContentType();

Put those values into a RestResponse Object that may also contain the response 
result itself.

Java (partly Python) client lacks:

- "*", /map, /version, /revision
- /sequence and /pulse for NativeGPIO
- all /devices/name/*/... paths
- /macro
- /...... generic like for e.g. routes
- JSON response handling helpers

Hope that helps just as a proposal list.

Andreas

Original issue reported on code.google.com by andreas....@googlemail.com on 5 Apr 2013 at 2:53

GoogleCodeExporter commented 9 years ago
I don't see the need except with proxied requests for this ones :
urlConnection.setRequestProperty("Content-Type", "text/plain");
urlConnection.setRequestProperty("Accept-Encoding", "identity");

Original comment by tro...@trouch.com on 5 Apr 2013 at 6:43

GoogleCodeExporter commented 9 years ago
When establishing a connection with my Android App to Webiopi from External 
using a OpenVPN Connection via GSM or 3G I got timeout exceptions from the 
HTTP/Socket layer. It looks that in this case the time needed to connect and 
sometimes read the sockets through the VPN tunnel is too long for the default 
values of Android.

Adding the possibility to set the Timeout parameters and using appropriate 
values solved the problem. Thats the reason why I added the possibility to set 
the timeout values for the UrlConnection. In my app these values are then set 
via preferences to allow fine-tuning when needed.

The extended response handling allows me to deal with errors and manage the 
response switching between plain text and JSON.

Original comment by andreas....@googlemail.com on 7 Apr 2013 at 2:33

GoogleCodeExporter commented 9 years ago
no problem about timeout, totally understand.
I asked about HTTP request headers Content-Type and Accept-Encoding

Original comment by tro...@trouch.com on 7 Apr 2013 at 2:59

GoogleCodeExporter commented 9 years ago
Concerning ("Accept-Encoding", "identity"):

This a excerpt from the description of java.net HttpURLConnection:

>>>>>
By default, this implementation of HttpURLConnection requests that servers use 
gzip compression. Since getContentLength() returns the number of bytes 
transmitted, you cannot use that method to predict how many bytes can be read 
from getInputStream(). Instead, read that stream until it is exhausted: when 
read() returns -1. Gzip compression can be disabled by setting the acceptable 
encodings in the request header: 

   urlConnection.setRequestProperty("Accept-Encoding", "identity");
<<<<<

As I was not sure if the Python BaseHttpServer handles gzip handling correct 
(or at all) I wanted to avoid this problem by just disabling it. As in most 
cases the amount of data exchanged via webiopi rest calls is very small gzip 
compression may just be an overhead.

Concerning ("Content-Type", "text/plain"):

I encountered some http response errors
when doing POST calls which do not POST content in the case of webiopi rest 
calls. Looks like some HTTP servers either need a POSTed content to try 
auto-discovery of the posted content or a Request-Header set appropriately so 
that auto-discovery is unnecessary. Seemed that if there is no content and no 
content-type request header they have a potential problem with this POST call. 
But I cannot remember exactly which kind of HTTP server it was at the time I 
tested it, maybe it was the NanoHTTPD for Java which I also used for testing 
some times and not the webiopi Python server.

So just keep this one as a backed-up possible solution if anyone else may 
encounter this kind of problem.

Andreas

Original comment by andreas....@googlemail.com on 8 Apr 2013 at 11:19

GoogleCodeExporter commented 9 years ago
Ok I see the problem with gzip and need for Accept-Encoding header.
For the content-type one, this is certainly due to NanoHTTPD POST handling like 
you say.
I will certainly check this and make changes this week.

Original comment by tro...@trouch.com on 8 Apr 2013 at 6:41

GoogleCodeExporter commented 9 years ago
Eric,

in the last days I read much details about Hadoop components family and its 
Java implementation (has nothing to do with my Raspi work). Looking how Hadoop 
is implemented I came across the way its configured at runtime. Aside other 
things it uses a Configuration class that allows dynamic configuration at 
runtime of many things. I found this an interesting approach that may also be 
of value for the Java Webiopi client package.

The way would be:

- define a Configuration Class thats instantiated with default values inside 
its constructor.
- When creating a PiClient it creates its own default configuration object or 
uses a configuration instance thats created somewhere else and provided to the 
constructor
- First use would be to create a configuration object with specific settings 
from Java code directly just before creating the PiClients
- Later you could add a subclass or methods to instantiate (and serialize back) 
the configuration object from external sources like config-files, XML-Files, 
JSON structures, jvm command-line arguments or whatever may make sense
- Maybe the PiClient can even be re-configured by setting a new configuration 
at runtime

Later within a Webiopi Android client app framework package a subclass could be 
added to read settings from a set of predefined (by pref keys) Android 
preferences.

Andreas

Original comment by andreas....@googlemail.com on 10 Apr 2013 at 8:25

GoogleCodeExporter commented 9 years ago
As additional information these are the classes I mean:

http://hadoop.apache.org/docs/current/api/org/apache/hadoop/conf/Configuration.h
tml
http://hadoop.apache.org/docs/current/api/org/apache/hadoop/mapred/JobConf.html

To start, just some methods would be sufficient like

public void setInt(String name,int value)
public void set(String name, String value)
public String get(String name, String defaultValue)
public int getInt(String name, int defaultValue)

The first arguments are the parameter identifiers. According to the examples in 
class JobConf they could be like

webiopi.http.connecttimeout
webiopi.http.readtimeout
webiopi.coap.port

Usage would be 

...
PiConf conf = new PiConf();
conf.setInt("webiopi.http.port", 8000);
conf.set("webiopi.http.user", "webiopi");
...
PiClient client = new PiClient(conf);
...

PiConf could then have additional methods to read/write to formats like XML, 
webiopi config, JSON etc.

And for Android I could provide a subclass that reads/writes from Android 
Preferences. Nicely the keys of the Preferences could be the same as the 
parameter names above.

Andreas

Original comment by andreas....@googlemail.com on 19 Apr 2013 at 9:47

GoogleCodeExporter commented 9 years ago

Original comment by tro...@trouch.com on 4 Jan 2014 at 9:00

GoogleCodeExporter commented 9 years ago

Original comment by tro...@trouch.com on 4 Jan 2014 at 9:01

GoogleCodeExporter commented 9 years ago

Original comment by tro...@trouch.com on 28 Jan 2014 at 9:13