Repository navigation
RaftWebServerSysMod
Built-in SysMod that hosts an HTTP server, exposes the REST API over HTTP, optionally serves static files, and registers WebSocket channels with the Comms Channels layer.
- HTTP server on a configurable port with a configurable REST API path prefix.
-
REST API bridge — every endpoint registered via
RestAPIEndpointManager::addEndpoint()is reachable asGET/POST/PUT/DELETE <prefix>/<endpoint>.... - Static file serving from any mounted file system (LittleFS / SPIFFS / SD).
-
WebSocket channels — each entry in the
websocketsarray becomes one or more comms channels using a chosen protocol codec. -
webcertsREST endpoint for uploading TLS certificates.
Place a WebServer block in the SysType SysMods array. Typical values:
| Key | Default | Meaning |
|---|---|---|
enable |
false |
Master switch |
webServerPort |
80 |
TCP listen port |
apiPrefix |
"api/" |
Path prefix for REST endpoints — api/subscription etc. |
fileServer |
true |
Enable static file handler |
numConnSlots |
12 |
Max concurrent HTTP connections |
stdRespHeaders |
[] |
Header lines added to every response |
staticFilePaths |
"/=/<defaultFS>,/files/local=/local,/files/sd=/sd" |
Comma-separated urlPath=fsPath pairs |
websockets |
[] |
Array of websocket configs (see below) |
taskCore, taskPriority, taskStack
|
platform defaults | Web server task |
sendMax |
20000 |
Max outbound data queued per connection (bytes) - see Memory use |
clearPendingMs |
0 |
If > 0, drop pending tx after this many ms |
Each connection can queue up to sendMax bytes of unsent data when the link drains slowly (e.g. weak WiFi). These buffers use PSRAM when the board has it and it is enabled (CONFIG_SPIRAM), and otherwise internal RAM, which WiFi and lwIP also need. With the defaults (12 slots × 20000 bytes) a board without PSRAM can run out of internal RAM under concurrent downloads.
On boards without PSRAM:
- Consider lowering
numConnSlotsandsendMax. - In RaftWebServer versions after 1.16.1, a send buffer that can't be grown, or a file chunk that can't be allocated, fails that connection instead of crashing.
- File downloads are read and sent in chunks of at most 4096 bytes (
RAFT_WEB_FILE_CHUNK_MAX_BYTES, which can be defined in the build to change it), rather than up tosendMax.
Each HTTP or WebSocket connection uses an lwIP socket and an active TCP connection, as do the listeners, mDNS, SNTP, NetBIOS, DNS and the application. The ESP-IDF defaults are too small for 12 connection slots, and when they run out new connections are reset by lwIP before the web server sees them. Recommended settings for the SysType's sdkconfig.defaults (or the project's systypes/Common/sdkconfig.defaults):
CONFIG_LWIP_MAX_SOCKETS=24
CONFIG_LWIP_TCP_ACCEPTMBOX_SIZE=16
CONFIG_LWIP_MAX_ACTIVE_TCP=32
In RaftWebServer versions after 1.16.1:
-
Startup warning: a warning is logged if
numConnSlotsplus the sockets other things typically need exceedsCONFIG_LWIP_MAX_SOCKETS. -
Busy response: a connection which can't be given a slot gets
503 Service UnavailablewithRetry-After: 1, rather than being closed (which the client sees as a reset). - Bursts: several waiting connections are accepted per main loop pass, so a burst of connections is handled.
With these settings a UM FeatherS3 served bursts of up to 24 simultaneous requests with no failures.
On boards with PSRAM, enable it in the SysType's sdkconfig.defaults (CONFIG_SPIRAM=y and the board's mode, e.g. CONFIG_SPIRAM_MODE_QUAD=y or CONFIG_SPIRAM_MODE_OCT=y). Note that in RaftCore 1.58.1 and earlier the PSRAM-aware buffers didn't use PSRAM under ESP-IDF 5 and later, even when it was enabled. This is fixed in later versions.
| Key | Default | Meaning |
|---|---|---|
pfix |
"ws" |
URL path prefix and channel interface name |
pcol |
"RICSerial" |
Protocol codec to attach (RICSerial, RICFrame, RICJSON) |
maxConn |
impl-defined | Max simultaneous websocket connections |
pingMs |
impl-defined | Ping interval |
txQueueMax |
impl-defined | Outbound queue depth |
Each connection slot is registered with CommsChannelManager as a channel named <pfix>_<idx>, so connection 0 to pfix:"ws" becomes channel ws_0. See Comms Channels.
| Endpoint | Method | Purpose |
|---|---|---|
webcerts/set |
POST | Upload TLS certificates (body = JSON document) |
Every other endpoint visible over HTTP comes from other SysMods registering with RestAPIEndpointManager. The web server simply forwards.
void serveStaticFiles(const char* servePaths, const char* cacheControl = nullptr);
void enableServerSideEvents(const String& eventsURL);
void sendServerSideEvent(const char* eventContent, const char* eventGroup);These are typically called from your application's setup() after RaftCoreApp::setup().
- Adding REST API Endpoints
- Communications Stack Overview
- Comms Channels
- Network Manager SysMod — required for an active network interface
Getting Started
- Quick Start
- Architecture at a Glance
- Writing Your First SysMod
- Adding a Comms Channel
- Adding an I2C Device Type
- PlatformIO / Arduino
Scaffolding & Building
- Raft CLI
- SysTypes
- Top-Level SysType
- Build Process
- WebUI Build Pipeline
- File System
- Partitions & Flash
- Local Dev Libraries
- Library Developer Guide
Architecture
Built-in SysMods
- NetworkManager
- WiFi Troubleshooting
- BLEManager
- WebServer
- MQTTManager
- SerialConsole
- CommandSerial
- CommandSocket
- CommandFile
- FileManager
- LogManager
- ESPOTAUpdate
- StatePublisher
- Remote Logging
- Data Source Registration
Comms & Protocols
- Stack Overview
- Comms Channels
- ProtocolExchange
- RICREST Protocol
- Real-Time Streams
- Adding REST Endpoints
- Built-in REST Endpoints
- File Download (OKTO)
- OTA Update Flow
Devices & Buses
- DeviceManager
- Device Manager REST API
- Device Factory & Classes
- Device Type Records
- Adding an I2C Device Type
- Device Data Publishing
- Data Logger
- I2C Bus
- I2C Device Scanning
- I2C ID & Polling
- MotorControl Overview
- MotorControl Config
- MotorControl Commands
ROS 2
Helpers
Reference
{ "name": "WebServer", "enable": 1, "webServerPort": 80, "apiPrefix": "api/", "fileServer": 1, "numConnSlots": 6, "stdRespHeaders": [ "Access-Control-Allow-Origin: *" ], "staticFilePaths": "/=/local,/files/sd=/sd", "websockets": [ { "pfix": "ws", "pcol": "RICSerial", "maxConn": 4, "txQueueMax": 20, "pingMs": 30000 } ], "taskCore": 0, "taskPriority": 5, "taskStack": 5000, "sendMax": 5000, "clearPendingMs": 0 }