General Advice on HTTP GET Request

#1

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

#2

Sure, one time is enough

Just try it

Also merge the 2 write lines and kill println

currentTime is unnecessary, just use millis()

0 Likes

#3

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.

0 Likes

#4

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

0 Likes

#5

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.

https://processing.org/reference/libraries/net/Client.html
https://processing.org/reference/libraries/net/Client_readString_.html

0 Likes

#6

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="";
}
0 Likes

#7

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.

0 Likes

#8

Using frameCount is much more simple. Thanks

0 Likes

#9

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?

0 Likes

#10

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

0 Likes

#11

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();
}

0 Likes

#12

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);
    }
  }
}
0 Likes