Help understanding code execution as it pertains to websockets

I am using this library here, so far it works great for my needs.

I am trying to figure out why the top println only runs once. Also the serial prints appear to only print out at 1 second at the fastest. Looking at the .accept part of the code from the library, I don’t immediately see a poll or something that waits, which would stop my main loop from running…

I’m not sure if that’s an obvious/known thing about the 1 second response speed, I’m using the ESP8266-01.

Even if I just have the version two of the code below it’s just stuck at the main poll.

I apologize this is a library-specific question but I am also looking for general info about websockets/loops/serial performance expectation.

Edit: to be clear this code works fine, I get into the inner loop when a client connects, as mentioned instead of printing every 1 ms it only prints every second.

Serial.println("poll");

  if (!clientActive) {
    auto client = socketServer.accept();
    clientActive = true;
 
    if (client.available()) {
      for (int i = 0; i < 60000; i++) { // 1 minute poll for messages
        if (client.available()) {
          auto msg = client.readBlocking();
          client.send(msg.data());
        } else {
          break;
        }
        Serial.println((String)"for"+i);
        delay(1);
      }
      clientActive = false;
    }
  }
  
  delay(serverPollDelay);

Version 2

Serial.println("poll");

  if (!clientActive) {
    auto client = socketServer.accept();
    clientActive = true;

  }

  delay(serverPollDelay);

instead of printing every 1 ms it only prints every second

why would it print every 1 ms? I see this before your delay

if (client.available()) {
          auto msg = client.readBlocking();
          client.send(msg.data());
        } else {
          break;
        }

and whilst I admit I've never used that library, the function name 'readBlocking()' seems to indicate that you'll be possibly stuck there for a while...

also if that call empties the incoming buffer, then the next time you loop, client.available() will be 0 and you'll break and exit the loop. So that would explain why you get only one print.

have you tried to dig into what the library actually does?

Thanks for your response.

My question is kind of poorly written and the last edit is more clear of the 1 ms part(in the for loop).

I actually realized a mistake too on my part. My websocket client's poll for testing is running every 1 second so that's why I'm seeing 1 second log intervals once it's connected(inside the for loop with 60,000 increments). I just tested it, setting it to 50 milliseconds, it works as expected.

I briefly looked into the library but I will admit is a little lower level than what I'm used to eg. JavaScript/Python. Granted it's still readable... just different notation eg. the :: instead of .

Now what I'm dealing with is the string I send eg. "forward" is often "dirty" as in characters are not correct for example fonward.

I'm using a 3.3 linear regulator before the ESP, I read on a thread somewhere you should use caps in/out. Also I'm using software serial and that apparently is more prone to errors than the actual serial pins. But may not make sense if the ESP is what's receiving socket hit(from client) and then sending info to Arduino by digital pins via. software serial.

So right now I have some append counter for the max string length I expect and checking/throwing out data if I don't get the string match eg. "forward" that I'm expecting... I don't know if that's bad design, there are certainly times where you have gaps(wrong values received)... until it starts over/gets correct string again.

edit:

also if that call empties the incoming buffer, then the next time you loop, client.available() will be 0 and you'll break and exit the loop

Yeah I think that is a good point, I think that's why the server closes itself after getting a message from the client and then it doesn't loop again to start over. Hence I added this janky internal loop to persist connection.

rambling furhter:

The control mechanism I have is interesting:

mobile interface hold button down, socket sends "forward forward forward" at some interval = while button is held down

I have that persisted loop mentioned above eg. 60,000 iterations keep alive... I will confirm if when that's done if the main loop starts again to establish a new connection(with same client) but not sure.

My concern is in the for loop, there is a while.serialAvailable check... so that probably takes longer than the 1 ms loop iteration... I don't know if buffers can "stack" as in I kill the client and there is a backlog of forward commands that the Arduino is still working through... it seems to be the case as when I closed my laptop lid, the forward command was still being ran(move servos).

I'll probably have to rework that... here's a code sample of what I have, client side I just have a setInterval sending a message to the socket connection(ESP).

This code is on the Nano side

String commandStr;
int appendCounter = 0;

void loop() {
  while (ESPserial.available()) {
    Serial.print("while");
    char c = ESPserial.read();
    commandStr += c;
    appendCounter += 1;

    if (commandStr == "forward") {
      moveForwardAlt();
      commandStr = "";
      appendCounter = 0;
    } else if (appendCounter > 7) {
      commandStr = "";
      appendCounter = 0;
    }
  }

  delay(1);
}