Demonstrates a minimal HTTP server for FastLED using the fl::HttpServer API.
Features
- Clean API: Route handlers using
fl::function<> callbacks
- Non-blocking: Integrates seamlessly with Arduino
loop()
- Type-safe:
http_request and http_response classes
- Visual feedback: LED colors indicate server state
- Educational: Clear example of HTTP server patterns
Routes
| Method | Path | Description |
| GET | / | Returns "Hello from FastLED!" |
| GET | /status | Returns LED status as JSON |
| POST | /color | Sets LED color from JSON body |
| GET | /ping | Health check (returns "pong") |
LED Status Indicators
| Color | State | Meaning |
| Blue (pulse) | STARTING | Server initializing |
| Green (solid) | RUNNING | Server ready |
| Cyan (flash) | REQUEST_RECEIVED | HTTP request received |
| Purple (flash) | RESPONDED | Response sent |
| Red (solid) | ERROR | Server failed to start |
Usage
1. Compile the Example
bash compile posix --examples Server
2. Run the Server
.build/meson-quick/examples/Server.exe
Expected output:
HTTP Server Example
Server started on http://localhost:8080/
3. Test with Python Client
uv run python examples/Asio/Server/test_client.py
Output:
FastLED Network Example Test Client
Server: http://localhost:8080
Waiting for server at http://localhost:8080/ping...
✓ Server is ready!
Sending 5 requests to http://localhost:8080/...
Request 1: ✓ 200 (2.3 ms)
Response: 'Hello from FastLED!'
...
┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Metric ┃ Value ┃
┡━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Total Requests │ 5 │
│ Successful │ 5 (100%) │
│ Failed │ 0 (0%) │
│ Min Response Time │ 1.8 ms │
│ Max Response Time │ 3.2 ms │
│ Avg Response Time │ 2.4 ms │
└───────────────────┴──────────┘
✓ All tests passed!
4. Test with curl
# GET /
curl http://localhost:8080/
# Output: Hello from FastLED!
# GET /status
curl http://localhost:8080/status
# Output: {"num_leds":10,"brightness":64,"uptime_ms":12345}
# POST /color (set LEDs to red)
curl -X POST http://localhost:8080/color -d '{"r":255,"g":0,"b":0}'
# Output: Color updated
# GET /ping
curl http://localhost:8080/ping
# Output: pong
Code Example
#include <FastLED.h>
});
response.set("status", "ok");
response.set("message", "Data received");
});
Serial.println(
"Server started!");
}
}
}
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
Response & json(const class json &data)
Set JSON response body with automatic Content-Type header.
static Response ok(const string &body="")
Factory method for 200 OK response.
static json object() FL_NOEXCEPT
asio::http::Request http_request
void delay(u32 ms, bool run_async=true) FL_NOEXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
asio::http::Server HttpServer
API Reference
HttpServer
Methods:
bool start(int port = 8080) - Start server on specified port
void stop() - Stop server and close connections
size_t update() - Process pending requests (call in loop())
void get(path, handler) - Register GET route
void post(path, handler) - Register POST route
void put(path, handler) - Register PUT route
void del(path, handler) - Register DELETE route
bool is_running() - Check if server is running
int port() - Get server port
string last_error() - Get last error message
http_request
Methods:
const string& method() - HTTP method ("GET", "POST", etc.)
const string& path() - Request path ("/api/status")
const string& body() - Request body (for POST/PUT)
optional<string> header(name) - Get header by name
optional<string> query(param) - Get query parameter
bool is_get() - Check if method is GET
bool is_post() - Check if method is POST
http_response
Methods:
http_response& status(int code) - Set HTTP status code
http_response& header(name, value) - Add HTTP header
http_response& body(content) - Set response body
http_response& json(data) - Set JSON response
Factory Methods:
http_response::ok(body) - 200 OK response
http_response::not_found() - 404 Not Found
http_response::bad_request(msg) - 400 Bad Request
http_response::internal_error(msg) - 500 Internal Server Error
Platform Support
- ✅ POSIX (Linux, macOS) - Full support
- ✅ Windows - Full support via fcntl emulation
- ❌ ESP32 - Not yet supported (different networking API)
- ❌ Arduino - Not supported (no networking stack)
- ❌ WASM - Not supported (browser doesn't allow servers)
Technical Details
Non-Blocking I/O
The HTTP server uses non-blocking sockets to integrate with FastLED's event loop:
- No select()/poll(): Compatible with WASM constraints
- MSG_DONTWAIT flag: Non-blocking recv() calls
- fcntl(O_NONBLOCK): Non-blocking socket mode
- Sequential polling: Simple client socket iteration
HTTP/1.0 Protocol
Minimal HTTP/1.0 implementation for simplicity:
- Request parsing: Method, path, headers, body
- Response generation: Status line, headers, body
- Connection: close: One request per connection
- Content-Length: Automatic header generation
Route Matching
Simple exact-match routing (no regex or wildcards):
server.get(
"/api/status", handler);
For advanced routing (wildcards, parameters), consider extending the HttpServer class.
Troubleshooting
Server won't start
ERROR: Failed to start server
Error: Failed to bind to port
Solution: Port 8080 may be in use. Try a different port:
Or kill the process using port 8080:
# Linux/macOS
lsof -ti:8080 | xargs kill -9
# Windows
netstat -ano | findstr :8080
taskkill /PID <PID> /F
Connection refused
Solution: Ensure the server is running before testing:
# Terminal 1: Run server
.build/meson-quick/examples/Server.exe
# Terminal 2: Run test client
uv run python examples/Asio/Server/test_client.py
Firewall blocking connections
Solution: Allow incoming connections on port 8080 in your firewall settings.
Next Steps
- Add authentication: Implement API key validation
- WebSocket upgrade: Add WebSocket support for real-time updates
- File serving: Serve static HTML files
- SSL/TLS: Add HTTPS support
- Rate limiting: Prevent abuse with request throttling
- Logging: Add request/response logging
See Also