FastLED 3.9.15
Loading...
Searching...
No Matches
Client Directory Reference
+ Directory dependency graph for Client:

Files

 Client.ino
 Educational tutorial for FastLED HTTP fetch API with explicit types.
 
 ClientReal.h
 
 test_server.py
 

Detailed Description

Educational tutorial for FastLED's HTTP fetch API (fl::fetch) with explicit types for learning.

Overview

This comprehensive tutorial demonstrates 4 different async approaches for HTTP networking in FastLED:

  1. Promise-based - JavaScript-like .then() and .catch_() callbacks
  2. Await-based - Synchronous-style fl::await_top_level() pattern
  3. JSON Promise - Promise pattern with automatic JSON parsing
  4. JSON Await - Await pattern with JSON response handling

The example cycles through all 4 approaches every 10 seconds with LED feedback to help you understand different async patterns.

Educational Focus

All types are explicitly declared (no auto) to help you understand FastLED's async type system:

LED Status Indicators

Color Approach Meaning
Green Promise-based HTTP success (.then)
Blue Await-based HTTP success (await)
Blue JSON Promise JSON parsed (promise)
Cyan JSON Await JSON parsed (await)
Red Any Network or HTTP error
Yellow JSON Promise Non-JSON response
Orange JSON Await Non-JSON response

Usage

1. Compile the Tutorial

# For WASM (recommended - full networking)
bash compile wasm --examples Client
# For POSIX (host-based testing)
bash compile posix --examples Client

2. Run the Tutorial

WASM (browser):

bash run wasm Client

POSIX (console):

.build/meson-quick/examples/Client.exe

3. With Local Test Server (Optional)

For testing without internet connection:

# Terminal 1: Start local test server
uv run python examples/Asio/Client/test_server.py
# Terminal 2: Modify tutorial to use localhost:8081
# (Edit ClientReal.h to change URLs from fastled.io/httpbin.org to localhost:8081)

Async Approaches Explained

APPROACH 1: Promise-based (.then/.catch)

JavaScript-like async pattern with method chaining:

fl::promise<fl::response> promise = fl::fetch_get("http://fastled.io");
promise.then([](const fl::response& response) {
if (response.ok()) {
FL_WARN("Success: " << response.text());
}
}).catch_([](const fl::Error& error) {
FL_WARN("Error: " << error.message);
});
#define FL_WARN(X)
Definition log.h:276

When to use:

APPROACH 2: Await-based (fl::await_top_level)

Synchronous-style code that blocks until completion:

fl::promise<fl::response> promise = fl::fetch_get("http://fastled.io");
fl::promise_result<fl::response> result = fl::await_top_level(promise);
if (result.ok()) {
const fl::response& response = result.value();
FL_WARN("Success: " << response.text());
} else {
FL_WARN("Error: " << result.error_message());
}

When to use:

⚠️ CRITICAL: await_top_level() blocks execution - ONLY use in loop(), NEVER in callbacks!

APPROACH 3: JSON Promise

Promise pattern with automatic JSON parsing:

fl::fetch_get("https://httpbin.org/json").then([](const fl::response& response) {
if (response.is_json()) {
fl::json data = response.json();
fl::string author = data["slideshow"]["author"] | fl::string("unknown");
FL_WARN("Author: " << author);
}
}).catch_([](const fl::Error& error) {
FL_WARN("Error: " << error.message);
});

Features:

APPROACH 4: JSON Await

Await pattern with JSON responses:

fl::promise<fl::response> promise = fl::fetch_get("https://httpbin.org/get");
fl::promise_result<fl::response> result = fl::await_top_level(promise);
if (result.ok() && result.value().is_json()) {
fl::json data = result.value().json();
fl::string origin = data["origin"] | fl::string("unknown");
FL_WARN("Origin: " << origin);
}

Combines:

API Reference

fl::fetch_get(url, options)

Make HTTP GET request:

// Simple GET
fl::promise<fl::response> promise = fl::fetch_get("http://example.com");
// With options (timeout, headers, etc.)
fl::fetch_options opts("");
opts.timeout(5000).header("User-Agent", "FastLED");
fl::promise<fl::response> promise = fl::fetch_get("http://example.com", opts);

fl::response

HTTP response object:

Methods:

fl::promise<T>

Represents future value:

Methods:

fl::promise_result<T>

Wraps success or error:

Methods:

fl::json

JSON object with safe access:

Methods:

Tutorial Behavior

The example automatically cycles through all 4 approaches:

0-10s: Approach 1 (Promise) → Green LEDs on success
10-20s: Approach 2 (Await) → Blue LEDs on success
20-30s: Approach 3 (JSON Promise) → Blue LEDs on success
30-40s: Approach 4 (JSON Await) → Cyan LEDs on success
40s+: Repeats from Approach 1

Watch the serial output and LED colors to understand each approach!

Platform Support

Common Patterns

Error Handling

Promise-based:

fetch_get(url).then([](const fl::response& r) {
if (!r.ok()) {
FL_WARN("HTTP error: " << r.status());
}
}).catch_([](const fl::Error& e) {
FL_WARN("Network error: " << e.message);
});

Await-based:

fl::promise_result<fl::response> result = fl::await_top_level(fetch_get(url));
if (!result.ok()) {
FL_WARN("Request failed: " << result.error_message());
}

Custom Headers

fl::fetch_options opts("");
opts.header("Authorization", "Bearer token123")
.header("X-Custom", "value")
.timeout(10000); // 10 seconds
fl::fetch_get("http://api.example.com/data", opts);

Multiple Parallel Requests

// Start multiple requests (non-blocking)
fl::fetch_get("http://api1.com/data").then(handle_api1);
fl::fetch_get("http://api2.com/data").then(handle_api2);
fl::fetch_get("http://api3.com/data").then(handle_api3);
// All requests run in parallel!

Troubleshooting

WASM: "Network request failed"

Cause: CORS policy blocking request

Solution: Use CORS-enabled endpoints or run local test server:

uv run python examples/Asio/Client/test_server.py

POSIX/Windows: "Connection refused"

Cause: Firewall or no internet connection

Solutions:

  1. Check firewall settings
  2. Use local test server (localhost bypasses firewall)
  3. Try different URL

"await_top_level blocked forever"

Cause: Used await_top_level() in callback context

Solution: Only use await_top_level() in loop(), use .then() in callbacks

Next Steps

See Also