Arduino server with depedent request/response

Hello,

I'm having a MKR1000 and would like to implement some protocol like this:

Step 1.1: Client -- Req 1 --> Server (MKR1000)
Step 1.2:        <-- Rep 1 --  (save some information)
Step 2.1:        -- Req 2 -->
Step 2.2:        <-- Rep 2 --

where the 2nd pair of request/response is dependent on the 1st one. In particular, I'd like to save some parameters from the first request so that I could use them to process the next one. Currently I'm using codes from the WifiWebServer example here.

For convenience, though the code below does not exactly reflect my protocol, it can demonstrate my problem: a number (n) is initialized when a client is connected and keeps being incremented at the server. For example, if n is initialized to 123 then at step 1.2 and 2.2 the server should send out 124, 125, respectively. However, my problem is the server closes the connection right after finishing the first request so n is reset back to 123, i.e. my client always receives two of 124 instead of 124, 125.

Is there any way that I can keep my session alive? Any advice is much appreciated. Thank you!

void loop() {
  // listen for incoming clients
  WiFiClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {

      int n = 123; // INITIALIZE MY NUMBER

      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply

        // EXTRACT INFO FROM CLIENT'S MESSAGE
        n = receive_from_client(); 

        if (c == '\n' && currentLineIsBlank) {

          n++; // INCREMENT THE NUMBER
          // SEND OUT THE NUMBER
          send_to_client(n);
          
          }
          
           break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

Post complete code and not just excerpts!

If you initialize you variable in the setup() routine it doesn't get reset and you can increase it with every request.

Out of curiosity: should that still be a web server? Is the client a browser? Is "Req 1" a HTTP request?

Hello ldt13,

What you want is to implement HTTP session like it is done in HTTPD with PHP or Tomcat with Java.

What you need to do is "remember" the client and to do so, those servers use 4 parameters :

  • source port ;
  • source ip address ;
  • destination port ;
  • destination ip address.

In your case the destination port is TCP 80 and the destination IP address is the one of your MKR1000 (assigned thought DHCP or set manually) and they are NOT changing.
The source port is likely to change through each request (number between 1025 and 65535) and therefore can't be used.

What is really identifying your client is its source IP address. You need to maintain an array of variables, in your case the 'n', for each IP addresses if you want to remember what was the state of the previous request with a particular client.

I don't own the MKR1000, but for the w5100 Ethernet Shield this thread is already covering the subject.

After looking at the class WifiClient on GitHub, apparently, it has the same function you need.

pylon:
Post complete code and not just excerpts!

If you initialize you variable in the setup() routine it doesn't get reset and you can increase it with every request.

Out of curiosity: should that still be a web server? Is the client a browser? Is "Req 1" a HTTP request?

Sorry for not being clear, my actual code has many unrelated computation functions so I just wanted to focus on the communication part. Actually I hard-coded my variable in the posted code for simplicity, the initial value is supposed to be obtained from the 1st request the client that's why I can't initialize it outside the loop.

For now I'm using apache httpclient for my client so yes, the messages are HTTP request and response but it doesn't need to be HTTP, as long as I can remember my client's information.

Do you need to handle multiple clients and store the information in what is usually called a session? Is a HTTP/1.1 protocol acceptable (so keep-alive will work)?