General Advice on HTTP GET Request

I have about 50 get requests to run at a the same time every time I iterate through the draw loop, and I’m trying to speed things up when connecting to them. One thing that takes about 100 milliseconds is the “c = new Client(this, “192.168.1.9”, 80);” line. My confusion is, why do I need to say “c = new Client” every time I want to “c.write” to send a get request? I saw some examples where you could declare your client address, then only use c.write when you need to send something to the server. I definitely have to have both lines in sequence for my GET to connect to the server.

Here’s the code, thanks:


import processing.net.*;

Client c;
Client c1;



String data;

void setup() {
  c = new Client(this, "192.168.1.9", 80); // Connect to server on port 80
  c.write("GET /blink?MIN=1010&MAX=1023&DURATION=1000 HTTP/1.0\r\n"); // Use the HTTP "GET" command to ask for a Web page
  c.write("\r\n");
}

long currentTime = 0;
long prevTime = 0;

void draw() {

  currentTime = millis();

  if (currentTime - prevTime > 2000) {
    prevTime = currentTime;
    println("blinking");
    c = new Client(this, "192.168.1.9", 80); // Connect to server on port 80
    c.write("GET /blink HTTP/1.0\r\n"); // Use the HTTP "GET" command to ask for a Web page
    c.write("\r\n");
  }

  if (c.available() > 0) { // If there's incoming data from the client...
    data = c.readString(); // ...then grab it and print it
    println(data);
  }
}
1 Like

Sure, one time is enough

Just try it

Also merge the 2 write lines and kill println

currentTime is unnecessary, just use millis()

No luck, triple checked. Processing requires me to run “c = new Client…” every time I want to do “c.write”

It wont connect otherwise, and the new Client line is the one that stalls the code.

It is weird

Think of a workaround though

You wait 2 seconds anyway

So use this time to initialize c again

Outside the if clause

I believe that this is the wrong way to initialize Client. You shouldn’t be hammering your poor server with new connection requests like that – and if you did it with a server you don’t control, you might get auto-blocked for DDOS-like behavior.

Have you tried using the test sketch from the reference? Does that work? Note that c needs to be a global variable to initialize in setup and then use in draw.

Instead of calling HTTP in draw() which could be called up to 60 times per second, you could store your data in a global variable and flush after calling HTTP req every second. I am assuming you are writing to the server.

Kf

String dataMemory="";

void draw(){
   dataMemory += "Time_in_ms: "+millis() + "\n";

   if(frameCount%60==0){  //Roughly every second
       flushData();
   }
}

void flushData(){

c = new Client(this, "192.168.1.9", 80); // Connect to server on port 80
    c.write(dataMemory); // Use the HTTP "GET" command to ask for a Web page
    c.write("\r\n");

  //Reset
  dataMemory="";
}

c = new Client(this, “192.168.1.9”, 80); // Connect to server on port 80
myClient = new Client(this, “127.0.0.1”, 5204); // From example sketch

The example sketch does work without issue. Mine still doesn’t unless I initialize the client every time before doing a c.write

Side note, the servers are ESP-8266.

Using frameCount is much more simple. Thanks

Maybe I need to send a “keep-alive” header?

The response I get from my server after a successful GET is:

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 55
Connection: close

Is there a way to write to my server to keep the connection open?

I am not familiar with the Client lib source code. Could you please provide details about your server configuration?

I am thinking you are using sockets to transfer the data. This is the way to transmit high rate real time data. For moderate or lower rates, my approach + http would be more convenient.

Kf

Took another stab at it, and yeah, your way is a lot faster. 2-3 ms to write to the server at its peak. Flushing the variable also makes it go about 20-40 ms faster too.

import processing.net.*;

Client c;

String data;
String dataMemory="";

void setup() {
}


void draw() {
  if (frameCount%120==0) {
    sendData();
  }
  //if (c.available() > 0) { // If there's incoming data from the client...
  //  data = c.readString(); // ...then grab it and print it
  //  println(data);
  //}
}


void sendData() {
  long startTime = millis();
  dataMemory = "GET /blink HTTP/1.0\r\n";
  c = new Client(this, "192.168.1.167", 80); // Connect to server on port 80
  c.write(dataMemory);
  c.write("\r\n"); // Use the HTTP "GET" command to ask for a Web page
  dataMemory = "";
  long endTime = millis();
  println();
  println("TIME TO SEND DATA: " + (endTime -= startTime));
  println();
}

Also, here’s what’s running on my esp

#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPUpdateServer.h>
#include <WiFiUdp.h>
#include "config.h"

String deviceHostname;

// Brightness values are between 0 and 1
float minBrightness = 0;
float maxBrightness = 1;
int blinkDuration = 100; // ms

bool blinking = false;
long blinkStartTime;

//======= HTTP SERVER SETUP
const char* update_path = "/update";
static String message = "";
static String mdnsres = "";
ESP8266WebServer server(80);
ESP8266HTTPUpdateServer httpUpdater;

// Handles route for '/'
void handleRoot() {
//  String localIP = String(WiFi.localIP());
  server.send(200, "text/plain", "hello joe");

}

// trigger
// max brightness
// min brightness
// total fade time

// Handles not found's (404s)
void handleNotFound() {
  message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";

  // Print out the query string parameters
  for (uint8_t i = 0; i < server.args(); i++) {
    message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  }

  server.send(404, "text/plain", message);
}

void handleHostname() {
  server.send(200, "text/plain", deviceHostname);
}

// Handles route for '/mdnsquery'
void handleMDNSQuery() {
  Serial.println("Sending mDNS query");

  int n = MDNS.queryService("http", "tcp"); // Send out query for esp tcp services
  mdnsres = "";

  Serial.println("mDNS query done");

  if (n == 0) {
    Serial.println("no services found");
  } else {
    for (uint8_t i = 0; i < n; ++i) {
      Serial.println(MDNS.hostname(i));

      // Save name of each valid hostname found - based on HOSTNAME prefix
      if (strncmp(MDNS.hostname(i).c_str(), HOSTNAME, 9) == 0) {
        mdnsres += MDNS.hostname(i);
        mdnsres += "\n";
      }
    }

    server.send(200, "text/plain", mdnsres);
  }

  Serial.println("mDNS Query Results:");
  Serial.println(mdnsres);
}

// Handles route for '/blink?MIN=0&MAX=100&DURATION=10000'
void handleBlink() {
  if (server.hasArg("MIN")) {
    float newMinBrightness = constrain(atoi(server.arg("MIN").c_str()), 0, 1023) / 1023.0;

    if (newMinBrightness < maxBrightness) {
      minBrightness = newMinBrightness;
    }
  }

  if (server.hasArg("MAX")) {
    float newMaxBrightness = constrain(atoi(server.arg("MAX").c_str()), 0, 1023) / 1023.0;

    if (newMaxBrightness > minBrightness) {
      maxBrightness = newMaxBrightness;
    }
  }

  if (server.hasArg("DURATION")) {
    float newDuration = (long)atoi(server.arg("DURATION").c_str());

    if (newDuration > 0 && newDuration < MAX_DURATION) {
      blinkDuration = newDuration;
    }
  }

  blinking = true;
  blinkStartTime = millis();

  message = "Blinking for ";
  message += blinkDuration;
  message += " ms from ";
  message += minBrightness * 100;
  message += "% to ";
  message += maxBrightness * 100;
  message += "% brightness.";

  server.send(200, "text/plain", message);
  Serial.println(message);

}

// Handles route for '/off'
void handleOff() {
  server.send(200, "text/plain", "LED off");
  blinking = false;
  setBrightness(0);
}

//============ SETUP

void setup() {
  Serial.begin(115200);
  Serial.println("Booting");

  // Set Hostname
  deviceHostname = HOSTNAME;
  deviceHostname += String(ESP.getChipId(), HEX);

  // Setup wifi
  WiFi.hostname(deviceHostname);
  WiFi.mode(WIFI_STA);
  WiFi.begin(SSID_NAME, SSID_PWD);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("Connection Failed! Rebooting...");
    delay(2000);
    ESP.restart();
  }

  // Setup mDNS Responder
  if (!MDNS.begin(deviceHostname.c_str())) {
    Serial.println("Error setting up MDNS responder!");

    while (1) {
      delay(1000);
    }
  }
  Serial.println("mDNS responder started");

  // Setup the LED
  pinMode(LED_PIN, OUTPUT);
  pinMode(LED_PIN1, OUTPUT);

  setBrightness(1);

  // Setup HTTP SERVER routes
  server.on("/", handleRoot);
  server.on("/hostname", handleHostname);
  server.on("/mdnsquery", handleMDNSQuery);
  server.on("/blink", handleBlink);
  server.on("/off", handleOff);
  server.onNotFound(handleNotFound);

  // Setup the remote updater on route '/update'
  httpUpdater.setup(&server, update_path);

  server.begin();
  MDNS.addService("http", "tcp", 80);
  Serial.printf("HTTPServer ready! Open http://%s.%s in your browser\n", deviceHostname.c_str(), LOCAL_EXT);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}

// brightness is 0 to 1 where 1 is brightest
void setBrightness(float brightness) {
  int pwmDutyCycle = constrain(brightness, 0, 1) * PWMRANGE;

  analogWrite(LED_PIN, pwmDutyCycle);
  analogWrite(LED_PIN1, pwmDutyCycle);
}

// A blink is from max brightness to min brightness and back again
void blink(float rawRatioComplete) {
  float ratioComplete = constrain(rawRatioComplete, 0, 1);

  // % of the range between min and max brightness
  float brightnessRatio = (ratioComplete < 0.5) ?
    (1 - ratioComplete * 2) :
    ((ratioComplete - 0.5) * 2);

  // The actual brightness to set
  float brightness = brightnessRatio * (maxBrightness - minBrightness) + minBrightness;

  setBrightness(brightness);
}


void loop() {
  server.handleClient();
  
  long currentTime = millis();

  if (blinking) {
    long blinkEndTime = blinkStartTime + blinkDuration;

    if (currentTime > blinkEndTime) {
      // Stop blinking
      blinking = false;
    } else {
      float blinkRatio = (currentTime - blinkStartTime) / (float)blinkDuration;
      blink(blinkRatio);
    }
  }
}
1 Like