Skip to content

RaftWebServerSysMod

Rob Dobson edited this page Oct 15, 2026 · 2 revisions

WebServer SysMod

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.

Source: RaftWebServer/components/WebServer/

What it provides

  • HTTP server on a configurable port with a configurable REST API path prefix.
  • REST API bridge — every endpoint registered via RestAPIEndpointManager::addEndpoint() is reachable as GET/POST/PUT/DELETE <prefix>/<endpoint>....
  • Static file serving from any mounted file system (LittleFS / SPIFFS / SD).
  • WebSocket channels — each entry in the websockets array becomes one or more comms channels using a chosen protocol codec.
  • webcerts REST endpoint for uploading TLS certificates.

SysType configuration

Place a WebServer block in the SysType SysMods array. Typical values:

{
    "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
}
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

Memory use

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 numConnSlots and sendMax.
  • 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 to sendMax.

Connection limits and lwIP settings

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 numConnSlots plus the sockets other things typically need exceeds CONFIG_LWIP_MAX_SOCKETS.
  • Busy response: a connection which can't be given a slot gets 503 Service Unavailable with Retry-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.

Websocket entry

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.

REST endpoints exposed

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.

Programmatic helpers

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().

Related

Clone this wiki locally