This is the "look under the hood" example. It reaches into the Layer-4 connection pool to report live TCP state, adds a zero-heap token-bucket rate limiter, profiles handler execution in microseconds, audits stack headroom, and does content negotiation in the 404 handler. Everything here is allocation-free.
#include "protocore.h"
static const char *SSID = "YOUR_SSID";
static const char *PASSWORD = "YOUR_PASSWORD";
PC server;
static unsigned long total_routed_requests = 0;
static unsigned long total_rate_limited = 0;
static float bucket_tokens = 5.0f;
static const float bucket_capacity = 5.0f;
static const float refill_rate_per_sec = 2.0f;
static unsigned long last_refill_time_ms = 0;
bool acquire_rate_limit_token()
{
unsigned long now = millis();
unsigned long elapsed_ms = now - last_refill_time_ms;
last_refill_time_ms = now;
bucket_tokens += (elapsed_ms / 1000.0f) * refill_rate_per_sec;
if (bucket_tokens > bucket_capacity)
bucket_tokens = bucket_capacity;
if (bucket_tokens >= 1.0f)
{
bucket_tokens -= 1.0f;
return true;
}
return false;
}
void print_connection_pool_stats()
{
Serial.println("\n--- Connection Pool Snapshot ---");
{
const char *state_str = "UNKNOWN";
{
case ConnState::CONN_FREE: state_str = "FREE"; break;
case ConnState::CONN_ACTIVE: state_str = "ACTIVE"; break;
case ConnState::CONN_CLOSING: state_str = "CLOSING"; break;
}
size_t rx_unread = 0;
if (conn->
state == ConnState::CONN_ACTIVE)
rx_unread = (conn->rx_head >= conn->rx_tail) ? (conn->rx_head - conn->rx_tail)
Serial.printf("Slot [%d]: State=%-7s | UnreadBytes=%4zu | LastActivity=%6lu ms ago | PCB=%p\n", i, state_str,
rx_unread, (conn->
state == ConnState::CONN_ACTIVE) ? (millis() - conn->
last_activity_ms) : 0, conn->pcb);
}
Serial.println("---------------------------------");
}
void handle_diagnostics(uint8_t slot_id,
HttpReq *req)
{
unsigned long start_us = micros();
total_routed_requests++;
if (!acquire_rate_limit_token())
{
total_rate_limited++;
server.send(slot_id, 429, "application/json", "{\"error\":\"Too Many Requests. Rate limit exceeded.\"}");
return;
}
UBaseType_t stack_high_water = uxTaskGetStackHighWaterMark(NULL);
char response_buf[384];
snprintf(response_buf, sizeof(response_buf),
"{"
"\"uptime_ms\":%lu,"
"\"routed_requests\":%lu,"
"\"rate_limited_count\":%lu,"
"\"free_heap_bytes\":%u,"
"\"task_stack_headroom_words\":%u,"
"\"bucket_tokens_left\":%.2f"
"}",
millis(), total_routed_requests, total_rate_limited, ESP.getFreeHeap(), (unsigned int)stack_high_water,
bucket_tokens);
unsigned long duration_us = micros() - start_us;
server.send(slot_id, 200, "application/json", response_buf);
Serial.printf(
"[Profile] GET %s handled in %lu us\n", req->
path, duration_us);
}
void handle_compute(uint8_t slot_id,
HttpReq *req)
{
unsigned long start_us = micros();
total_routed_requests++;
if (!acquire_rate_limit_token())
{
total_rate_limited++;
server.send(slot_id, 429, "application/json", "{\"error\":\"Too Many Requests\"}");
return;
}
volatile uint32_t val = 12345;
for (int i = 0; i < 500; i++)
val = (val ^ 37821) * 31;
char response_buf[64];
snprintf(response_buf, sizeof(response_buf), "{\"result\":%u}", val);
server.send(slot_id, 200, "application/json", response_buf);
unsigned long duration_us = micros() - start_us;
Serial.printf(
"[Profile] GET %s (heavy compute) handled in %lu us\n", req->
path, duration_us);
}
void handle_expert_not_found(uint8_t slot_id,
HttpReq *req)
{
unsigned long start_us = micros();
total_routed_requests++;
const char *accept_header = http_get_header(req, "Accept");
bool wants_json = (accept_header && strstr(accept_header, "application/json") != nullptr);
char error_buf[256];
if (wants_json)
{
snprintf(error_buf, sizeof(error_buf), "{\"error\":\"not_found\",\"requested_path\":\"%s\",\"uptime\":%lu}",
server.send(slot_id, 404, "application/json", error_buf);
}
else
{
snprintf(error_buf,
sizeof(error_buf),
"--- Error 404 ---\nPath: %s\nUptime: %lu ms\nESP32 node", req->
path,
millis());
server.send(slot_id, 404, "text/plain", error_buf);
}
unsigned long duration_us = micros() - start_us;
Serial.printf("[Profile] Fallback 404 matched in %lu us (JSON: %d)\n", duration_us, wants_json);
}
void setup()
{
Serial.begin(115200);
delay(1000);
Serial.println("\n--- PC Expert Performance Example ---");
Physical.wifi->init(SSID, PASSWORD);
while (!Physical.wifi->ready())
{
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi online!");
Serial.print("Local IP: ");
uint32_t ip = Physical.link->egress_ip();
Serial.printf("IP: %u.%u.%u.%u\n", (unsigned)(ip & 0xFF), (unsigned)((ip >> 8) & 0xFF),
(unsigned)((ip >> 16) & 0xFF), (unsigned)((ip >> 24) & 0xFF));
last_refill_time_ms = millis();
server.on_not_found(handle_expert_not_found);
int32_t result = server.begin(80);
if (result < 0)
{
Serial.printf("begin() failed (error %d)\n", result);
return;
}
Serial.println("Telemetry server started on port 80");
}
void loop()
{
server.handle();
static unsigned long last_snapshot = 0;
if (millis() - last_snapshot >= 5000)
{
last_snapshot = millis();
print_connection_pool_stats();
}
}
#define MAX_CONNS
Maximum simultaneous TCP connections (fixed static pool; ~3.95 KB of internal RAM per slot).
@ HTTP_GET
Safe, idempotent read.
Layer 1 (Physical) - link bring-up, the interface registry, and live egress reporting.
A single TCP connection context.
uint32_t last_activity_ms
protocore_millis() timestamp of last TX/RX event.
_Atomic ConnState state
Lifecycle state; acquire/release for inter-task visibility.