An embedded, high-performance HTTP server for R based on the CivetWeb C library.
- Thread Safety: Uses a "Pull" model where multi-threaded C (50 worker threads) handles socket I/O and a single R thread processes logic, ensuring the R interpreter never crashes or deadlocks.
- WebSockets: Full support for bi-directional, stateful communication (Open, Message, and Close events).
- Routing: Support for method-based routing and path grouping.
- Static Content: Built-in static file serving with directory listing, breadcrumbs, and security guards.
civetwebR makes it easy to build stateful, reactive applications:
on_ws("open", function(req) {
message(sprintf("Client %s connected", req$id))
})
on_ws("message", function(req) {
msg <- rawToChar(req$body)
ws_send(req$id, paste("Echo:", msg))
})
on_ws("close", function(req) {
message(sprintf("Client %s disconnected", req$id))
})- Flexible I/O: Support for custom headers, query parameter parsing, and binary (raw) request/response bodies.
- Interrupt Friendly: Fully supports
Ctrl+Cto stop the server gracefully from the R console.
# Install from GitHub
# devtools::install_github("vedoa/civetwebR")library(civetwebR)
# Start a server on port 8080
serve(port = 8080, host = "127.0.0.1")handle("GET", "/path", function(req) "ok")Serve files directly from disk:
serve(
port = 8080,
static = list(
list(dir = "public", prefix = "/")
)
)Group routes under a common prefix:
group("/api", {
handle("GET", "/hello", function(req) "hi")
})req <- list(
method = "...",
path = "..."
)Character:
"ok"→ 200 text/plain
List:
list(
status = 200L,
headers = list(),
body = "data"
)- All handlers run in the R thread
- No concurrency in user code
MIT