HTTP request optimization

Hello,

I've just buy the industrial 101 (same as Yun, but lighter) and I'm very happy about it :).

My question is: the "loop" over the bridge for the an http request take at least 1.5 seconds, can we decrease that time? The main program run on the 32u4. On the other side, run a web server with some control over the program, like sending parameters or state.

I've have tried many different protocol, from basic HTML to Ajax, but the bottleneck seems to be the bridge. The 32u4 react "instantly" to the request, but take the 1.5 seconds to parse data.

I'm using the standard bridge library:

YunServer server;
Bridge.begin();
server.listenOnLocalhost();
server.begin();

YunClient client = server.accept();
  if (client) {
    String command = client.readStringUntil('/'); 
    command.trim();

And on the html side, i'm using the XMLHttpRequest().

var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() { 
        if (xhr.readyState == XMLHttpRequest.DONE) {
            toReceive = xhr.responseText;
            parseInfo(toReceive);
        }
    }
    toSend = encodeURIComponent(toSend);
    xhr.open('GET', '/arduino/'+toSend);
    xhr.send(null);

Do you have any tips or idea how I can increase the speed of the communication?

Thanks Mike

daprophet: but the bottleneck seems to be the bridge.

Yes, the bridge is indeed the bottleneck. Using YunServer and YunClient to implement an HTML or AJAX interface is easy, but very inefficient.

The 32u4 react "instantly" to the request, but take the 1.5 seconds to parse data.

No, the AR3391 reacts "instantly." That delay is getting the data up to the '32U4 and back down again through the bridge.

What's happening is that the HTML request is getting sent to the web server running on Linux on the AR3391. It parses the request, and see that the first token in the URL after the address is "/arduino/" so it sends the rest of the URL after that token up through the bridge to the '32U4 processor. The sketch receives that data through the YunServer/YunClient connection, parses the URL, and sends a response. That response is sent down through the bridge to the AR3391, which formats it as an HTML response, which gets sent back to the node making the initial request.

The serial port that is the bridge between the two processors is relatively slow (at least compared to the speed of the AR9331 processor and the network connection) and the speed of the '32U4 is also slow compared to the AR9331 processor. Using YunServer/YunClient is easy, but it's probably the slowest way to service HTTP requests.

Do you have any tips or idea how I can increase the speed of the communication?

Yes. Handle the requests completely on the AR9331 processor using code on the Linux side, and forget about trying to handle the HTML requests in the sketch.

I have built several projects on the Yun, and found that that the most efficient and responsive way to use it is to do all of the heavy processing (and certainly all of the network processing) on the Linux side of the system, and only use the sketch as an I/O processor to access the shield pins. An example of such a system is HERE.

That system does all of the "business" logic in Linux: responding to web requests, determining what should happen when, and tracking the system status. All of that logic is implemented in a Python script that periodically prints out the required output status, and periodically reads in the status of inputs. In this case, there is one output: a relay; and one input: an analog value representing the current draw.

The sketch consists of a Process object from the Bridge Library that runs the Python script. When the Python script uses a "print" statement to write out the desired output state, the sketch can read that from the Process object using the available() and read() methods. When new data is available from the Process object, the sketch reads the data, and controls the outputs as commanded. The sketch also periodically reads the analog input, and writes the raw data to the Process object, which the Python script can read as standard input: it reads the raw value, converts it to Amps, and does the appropriate processing.

Then there is the web service logic. For that, I write an application in Python using the Bottle Web Framework. (There are others out there as well, if you would prefer a different framework.) This Python script is launched by the sketch using another Process object. The resulting Bottle application serves up all of the dynamic and static HTTP requests and responses.

Where I was getting similar 1 to 1.5 second response time using YunServer/YunClient, using Bottle on the Linux side I am getting AJAX call response times in the range of a few tens of milliseconds.

Thank you for the quick and detailed reply. As you said, the YUNserver/YUNclient is an "quick & easy" solution but performances are a bit outdated.

I will work forward on the AR9331 now!

daprophet: the YUNserver/YUNclient is an "quick & easy" solution but performances are a bit outdated.

It's an easy migration path for those who are comfortable with Arduino programming, but wants to add some networking abilities to their sketches without having to learn programming on the Linux side. It works, but it is not high performance, but is probably good enough for a lot of applications.

But if you are willing to learn some programming on the Linux side of the machine, then the Yun becomes a VERY powerful platform: the Linux side provides high performance computing and networking, while the sketch side provides true real time hardware control.

In my mind, most of the Bridge Library is there to ease the transition for the traditional Arduino programmer: it's not necessary to learn much on the Linux side to include basic file and network features into a sketch. But once one is familiar with programming on the Linux side, I think the only truly useful feature of the Bridge Library is the Process class - that's about the only part of the Bridge that I use these days.