ESP8266 wi-fi client and server simultaneously

Hello coders,
I need to send and to receive data via wifi, the problem is the server is not responding when i add the client part (if i comment the client, server responds fine).
For what i understand the problem is the server watchdog timeout, so i should be able to avoid it with delay() and wdtDisable() but i cannot make it work.

I will use the ESP as a "modem" for my Arduino so it should be able to call the web (a) or receive a call from the web (b) as soon as new data is available from Arduino (a) or from the web (b).

Thanks

#include <WiFiClient.h>
#include <ESP8266WebServer.h>

const int httpPort = 80;
const char* ssid     = "ssid"; 
const char* password = "password";
ESP8266WebServer server(80);
WiFiClient client;
const char* host = "www.test.com";
char* url = "";
String str;

void setup() {
    Serial.begin(74880);    
    WiFi.disconnect(); // Disconnect AP
    WiFi.mode(WIFI_STA);  
    WiFi.begin(ssid, password); // Connect to WIFI network

    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println(".");
    }
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
  
    server.on("/endpoint", handleWebToArduinoRequests);
    server.begin(); // Start HTTP server
    Serial.println("HTTP server started.");

    //ESP.wdtDisable(); // try #1
    // while(1);        // 
}
  
void loop() {   
    server.handleClient();
    
  
    client.stop();
    if (!client.connect(host, httpPort)) {
        // delay(0); // try #2
        Serial.println("connection failed");
        return;
    }
    
    String msg = "";
    while(Serial.available()==0) { 
      // delay(0); // try #2
    }
    msg = Serial.readString();
    Serial.println(msg);

    Serial.print("Requesting URL: ");
    char* fullurl = strcat("/temp/grover/ajax/moduli/api/redneck/endpoint?", msg.c_str());
    Serial.println(fullurl);
    client.print(String("GET ") + fullurl + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
    
    client.println("Connection: close");
    client.println();
    int timeout = millis() + 5000;
    while (client.available() == 0) {
        // delay(0); // try #2
        if (timeout - millis() < 0) {
            Serial.println(">>> Client Timeout !");
            client.stop();
            return;
        }
        String line = client.readStringUntil('\r');
        Serial.print(line);
    }
    Serial.println();
    Serial.println("closing connection");
}

void handleWebToArduinoRequests() {
    // delay(0); // try #2
    String message = "";
    for (int i = 0; i < server.args(); i++) {
        message += server.argName(i) + ": " + server.arg(i) + "\n";
    } 
    Serial.println(message);
    server.send(200, "text/plain", message);       //Response to the HTTP request
}
void loop() {   
    server.handleClient();
   
 
    client.stop();

Doesn't matter that there might not be a client to stop, apparently. Here's a clue. It most certainly does.

    while(Serial.available()==0) {
      // delay(0); // try #2
    }

On EVERY pass through loop(), wait, doing NOTHING, for there to be serial data to read.

Why on earth would you do THAT?

You haven't a clue how/when to read serial data. Get one. Serial input basics - updated

Actually, someone suggested to manage all from Arduino, using ESP as a slave.

But now the problem is that if I call a remote server from Arduino client, when it reply (with a webpage) it is interpreted as a new connection to the Arduino server, messing up the request.

Server is listening char-by-char and it thinks the message is finished when it find \r char
On the other side Client response is a web page with a lot of \n and \r

loadServer();
loadClient();
if you comment loadServer() you can see the correct response to the client request.

The Question is: calls and relative requests should be automatically handled with the socket_id inside the WiFiEsp.h class? Am I wrong? Why it is not working?
Do I have to modify my code?

If not possible to distinguish server/client incoming messages using socket_id,
maybe I need to wait the message is finished (how?) and the analyze the content to understand if it for the client or for the server? (poor performance solution, I think)

My actual code is

#include "WiFiEsp.h"

const char* ssid         = "ssid";
const char* password     = "password";
int status = WL_IDLE_STATUS;     // the Wifi radio's status
int reqCount = 0;
char webServer[] = "www.voidbrain.net";
String url = "/temp/grover/ajax/moduli/api/redneck/endpoint";
String params = "";

WiFiEspServer ArduinoServer(80);
WiFiEspClient webClient;

void setup() {
  Serial.begin(115200);
  Serial1.begin(115200);
  WiFi.init(&Serial1);

  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while (true);   // don't continue
  }
  while ( status != WL_CONNECTED) { // attempt to connect to WiFi network
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, password);
  }
  Serial.println("You're connected to the network");
  printWifiStatus();

  ArduinoServer.begin();
}

void loop() {
  while (webClient.available()) { // reply from remote. if Arduino server is running this is not working
    char c = webClient.read();
    Serial.write(c);
  }

  loadServer();
  loadClient();
}

void loadServer(){
  // listen for incoming clients
  WiFiEspClient serverConnection = ArduinoServer.available();
  if (serverConnection) {
    Serial.println("New client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (serverConnection.connected()) {
      if (serverConnection.available()) {
        char incomingMessage = serverConnection.read();
        // 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
        if (incomingMessage == '\n' && currentLineIsBlank) {
          Serial.println("Sending response");
          
          // send a standard http response header
          // use \r\n instead of many println statements to speedup data send
          serverConnection.print(
            "HTTP/1.1 200 OK\r\n"
            "Content-Type: text/html\r\n"
            "Connection: close\r\n"  // the connection will be closed after completion of the response
            "Refresh: 20\r\n"        // refresh the page automatically every 20 sec
            "\r\n");
          serverConnection.print("<!DOCTYPE HTML>\r\n");
          serverConnection.print("<html>\r\n");
          serverConnection.print("<h1>Hello World!</h1>\r\n");
          serverConnection.print("Requests received: ");
          serverConnection.print(++reqCount);
          serverConnection.print("
\r\n");
          serverConnection.print("Analog input A0: ");
          serverConnection.print(analogRead(0));
          serverConnection.print("
\r\n");
          serverConnection.print("</html>\r\n");
          break;
        }
        if (incomingMessage == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (incomingMessage != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(10);

    // close the connection:
    serverConnection.stop();
    Serial.println("Client disconnected");
  }
}

void loadClient(){
  while (Serial.available()) {
    params = Serial.readString(); // "azione=accendi&sensore_id=12"
    httpRequestToWebServer();
  }
}

// this method makes a HTTP connection to the server
void httpRequestToWebServer() {
  webClient.stop(); // close any connection before send a new request, this will free the socket on the WiFi shield

  if (webClient.connect(webServer, 80)) {
    Serial.println("Connecting...");
    params = "azione=accendi&sensore_id=12"; // just for test
    webClient.println(String("GET ") + url + String("?") + params + String(" HTTP/1.1"));
    webClient.println(String("Host: ")+webServer);
    webClient.println("Connection: close");
    webClient.println();
    Serial.println(String("url: ")+webServer+url+ String("?") + params);
  } else {
    Serial.println("Connection failed");
  }
}


void printWifiStatus() {
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Do I have to modify my code?

Of course you do.

void httpRequestToWebServer() {
  webClient.stop(); // close any connection before send a new request, this will free the socket on the WiFi shield

ASSuming that webClient is a connected client is NOT a good idea.

What is the point of making a GET request and not reading the server response? Perhaps a clue-by-four would present itself.

void loadClient(){
  while (Serial.available()) {
    params = Serial.readString(); // "azione=accendi&sensore_id=12"
    httpRequestToWebServer();
  }
}

Excuse my ignorance, but why the hell is that a while loop?

But now the problem is that if I call a remote server from Arduino client, when it reply (with a webpage) it is interpreted as a new connection to the Arduino server, messing up the request.

That statement doesn't make sense.

You make a GET request, but you neither read the response, which will cause the connection to be properly closed once all the data has been read nor explicitly close the connection (telling the server to f**k off).

Do one of them, and I'll bet your issues get cleared up.

Everything was in the WebClientRepeating.ino and WebServer.ino sample code sketches, I am just trying to mix them.

void httpRequestToWebServer() {
  webClient.stop(); // close any connection before send a new request, this will free the socket on the WiFi shield

is in the WebClient sample. Why you say I am not not reading response to client?
As I said if you comment loadServer you see the response coming

You make a GET request, but you neither read the response

the client code shows the reply is read in the main loop

while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

Why you say I am not not reading response to client?
I repeat, if you comment loadServer you see the response coming.

void loadClient(){
  while (Serial.available()) {
    params = Serial.readString(); // "azione=accendi&sensore_id=12"
    httpRequestToWebServer();
  }
}

xcuse my ignorance, but why the hell is that a while loop?

I just would like to obtain this:
Arduino runs in loop, reading from sensors (we say every hour), maybe running some servos and the sends datas to a remote server.
The remote server can send to Arduino commands (tell me your status, read sensor n10, stop servo n4 ... etc )

Maybe It is a wrong approach, just for testing by the way: I just wanted to test the client when new data are available (emulating from serial) and I have not built the 1-hour loop code.

As I said if you comment loadServer you see the response coming

I can't see how that is possible, so I can't help any more.