ESP Server-Client: Client Data to Server

I have a server-client arrangement (ESP32/8266 - to - ESP32/8266) where the client sends a request and gets data back.
Is it possible to get data from the client to the server ("client to server, data packet for you")?
Just an int (or a float, maybe a string).

Sure, client to server is easy..
client connects, send a request..
but to have server to client can be a bit tricky..
depends on the server..
could use udp, server could broadcast the request for data..

~q

To re-cap, I can get data from server to client already.

  server.on("/bigTime", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    timeData();
    
    request->send_P(200, "text/plain", bufr);
  });

That makes the server look at its millis() and send it back to the client.

Perhaps there's a way for the client to send its data to the server as part of its request?
All I can think of is having URL paths for every contingency - which would be clunky, verging on impractical.

http, haven't worked with AsyncWebServer..
if they have a file upload example, maybe look into it..
~q

omg

Maybe HTTP POST would do what you want. Info at randomnerd.
I tend to use websockets for 2 way communication with my ESP32 web server, but that's for a relatively complicated interactive WEB UI for a preamp. For just a little data, perhaps HTTP POST would be more appropriate

Use query parameters

/bigTime?one=2&three=four&etc=etal

Have a common routine to extract and parse those. Fallback: custom request headers.

More formally, a GET is supposed to be idempotent, so if the client data changes something on the server side, it should be a POST, even one with no body. But if you've already got all the server->client set up and just want to add those client->server parameters, no one else would know.

I based the server-client that I'm using on RNT's example, though I had to pick it apart on my own. He's really stuck on BME temp sensor and structs. I had been looking for something more 'hello world'. His http_post article is wrapped up in node-red, another complication.

Idempotence asidemy plan for the data from the client would be something simple - put up on a display the server might have or a microSD.

I'm not sure if I understand your problem right so I apologise in advance. Are you askin how to recognize URL text sent by client based ob server.on function? I guess this may be a little difficult.
One way to get around it is using basic WiFiServer like WiFiServer webServer (80); You can read the whole HTTP request in a String (the whole URL would be in the first line of HTTP request) before sending the reply. Then you can parse it as you wish.

#include <WiFi.h>

WiFiServer webServer (80);

void loop () {
    WiFiClient webClient = webServer.accept ();
    if (webClient) {
        String httpRequest = "";
        while (webClient.connected ()) {
            if (webClient.available ()) {
                char c = webClient.read ();
                if (c == '\n' || c == '\r') { // read the HTTP request only until the first \n and discard the rest (although this information may be useful)
                    Serial.println ("Beginning of HTTP request from " + webClient.remoteIP ().toString () + ":\r\n" + httpRequest); 

                    String httpReplyBody = "<HTML><BODY>This page has been accessed.</BODY></HTML>"; // always send a similar reply
                    Serial.println ("Body of HTTP reply:\r\n" + httpReplyBody);
                    webClient.print ("HTTP/1.1 200 OK\r\n"
                                    "Content-type: text/html\r\n"
                                    "Connection: close\r\n"
                                    "Content-Length: " + String (httpReplyBody.length ()) + "\r\n"
                                    "\r\n" +
                                    httpReplyBody);
                    webClient.stop ();
                    return;
                }
                // else keep reading the httpRequest
                httpRequest += c;
            }
        }
    }
}

The dilemma is fundamental: how to send a char from the client to the server, assuming such a thing is possible.

All I can think of, to send 'X' or 'Y' (keeping things elementary) would be the client initiating some httpGETrequest accordingly --

// either, as appropriate . . .
httpGETRequest ("http://192.168.4.1/Xchar"); 
httpGETRequest ("http://192.168.4.1/Ychar");

The server would get the request, note the 'X' (or the 'Y') and then go on awaiting further opportunities to be of service --

  server.on("/Xchar", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    // X_counter ++; OR (??) print an X on OLED ??
    //request->send_P(200, "text/plain", bufr);
  });

  server.on("/Ychar", HTTP_GET, [](AsyncWebServerRequest *request)
  {
    // Y_counter ++; OR (??) print a Y on OLED ??
    //request->send_P(200, "text/plain", bufr);
  });

Seems it should work, but I haven't tried it.
Wondering if there might be a better way.

Use query parameters

httpGETRequest("http://192.168.4.1/?thatonechar=X"); 
httpGETRequest("http://192.168.4.1/?thatonechar=Y");
httpGETRequest("http://192.168.4.1/bigTime?thatonechar=X"); 
httpGETRequest("http://192.168.4.1/bigTime?thatonechar=Y");

So the client can send one character along with an actual request like /bigTime; or if it needs to send only, you could do that on the empty request path /.

You should pick a better name for the query parameter than thatonechar. You can also send any number of query parameters, separated by &. If the single char you are sending has a "reserved purpose" in the query string of an URL, like '&' or '%', then it must be percent-encoded

The SimpleServer example shows how to read a query parameter with hasParam and getParam

  // Send a GET request to <IP>/get?message=<message>
  server.on("/get", HTTP_GET, [](AsyncWebServerRequest* request) {
    String message;
    if (request->hasParam(PARAM_MESSAGE)) {
      message = request->getParam(PARAM_MESSAGE)->value();
    } else {
      message = "No message sent";
    }
    request->send(200, "text/plain", "Hello, GET: " + message);
  });

Thanks. I'll pore over this - and see what I come up with.

You should pick a better name for the query parameter than thatonechar.

It was spur of the moment, you know, very foo-like.