dr_ws(app, path, on_message, on_connect, on_close) —
register a WebSocket endpoint served by R hooks. Hooks run on the main R
thread; each receives a drogon_ws_conn handle.dr_ws_send(conn, msg, binary) /
dr_ws_close(conn) — push a message to, or close, a live
connection from any hook.dr_ws_join(conn, room) /
dr_ws_leave(conn, room) /
dr_ws_broadcast(room, msg, binary) — named broadcast rooms,
so a message can fan out to every member without tracking handles.dr_ws_cpp(app, path, package, callable) — R-bypass fast
path: a compiled C handler (ABI drogonr_ws_handler_t in
inst/include/drogonR.h) services every frame on Drogon’s
I/O thread, with a thread-safe
send/close/is_connected callback
set usable from a detached backend thread (e.g. an LLM streaming tokens
from C++ without a per-token round-trip through R).dr_ws_cpp() gains continuous-batching guards for
scheduler backends: max_conns (refuse an over-capacity
connection with WS close 1013), idle_timeout (reap a
connection with no outgoing frame for that long), and
max_lifetime (absolute duration ceiling). All default to
off.htonll under Emscripten), a [[nodiscard]]
warning under clang, and two rchk PROTECT-balance findings in the JSON
writer and response builder.dr_rate_limit(app, capacity, window, type, scope, routes)
— per-route or shared rate limit (sliding / fixed window or token
bucket); over-budget requests get HTTP 429 + Retry-After
from the I/O thread before R is involved.rate-limiting.Rmd.dr_stream(next_chunk, state, ...)
returns HTTP chunked responses driven by an R generator pumped on the
main R thread, with a cancelled = TRUE cleanup contract on
client disconnect.dr_stream_sse(generator, ...) convenience wrapper that
formats Server-Sent Events frames (multi-line data is split
per the SSE spec) and adds the Cache-Control: no-cache /
X-Accel-Buffering: no headers expected by typical SSE
clients.streaming.Rmd with the threading caveats
and end-to- end examples.dr_get("/users/:id", ...).
Three placeholder syntaxes are accepted interchangeably —
:name, <name>, {name} — and
exposed to handlers as a named character vector in
req$params.dr_text(), dr_html(),
dr_redirect(), dr_file().
dr_file() auto-detects the MIME type from a built-in table
covering ~25 common extensions, supports download_as = ...
for Content-Disposition: attachment, and warns/errors on
oversized loads (>50MB / >500MB).pipe(2)
/ fcntl(2) wakeup mechanism with a loopback TCP
socketpair on Windows. (Full Windows binary build is still
pending.)dr_json(): new C++ walker for basic types replaces
jsonlite. Hits 118k req/s (12x boost) with silent fallback.mcparallel (fork) to
processx (spawn). Fixes later fds and sink
stack issues in tests; ensures a clean R state for each worker.dr_serve(workers = N) spawns N
forked R workers sharing the listening port via
SO_REUSEPORT.on_worker_start callback in dr_serve() for
per-worker initialization (load models, open per-worker resources).dr_status() reports the live worker pids of a
multi-process serve.dr_serve(max_queue = N) bounds the request queue and
rejects excess requests with HTTP 503, providing backpressure under
overload.Initial development release.
pkg-config or a
manual search), the package is built with TLS enabled. Otherwise it
falls back to a plain-HTTP build with a single message at install
time.--with-openssl / --without-openssl flags
can force the choice (passed via
R CMD INSTALL --configure-args=...).<random> instead
of libuuid, removing the system dependency on Linux.