Skip to contents

Creates a server that can handle HTTP requests and WebSocket connections.

Usage

http_server(url, handlers = list(), tls = NULL)

Arguments

url

URL to listen on (e.g., "http://127.0.0.1:8080").

handlers

A handler or list of handlers created with handler(), handler_ws(), etc.

tls

TLS configuration for HTTPS/WSS, created via tls_config().

Value

A nanoServer object with methods:

  • $start() - Start accepting connections

  • $close() - Stop and release all resources

  • $serve() - Start and block, processing requests via the later event loop until interrupted (e.g., Ctrl+C). The server is automatically closed on exit

  • $url - The server URL

Details

This function leverages NNG's shared HTTP server architecture. When both HTTP handlers and WebSocket handlers are provided, they share the same underlying server and port. WebSocket handlers automatically handle the HTTP upgrade handshake and all WebSocket framing (RFC 6455).

WebSocket and streaming callbacks are executed on R's main thread via the later package. To process callbacks, you must run the event loop (e.g., using run_event_loop() in a loop), or use $serve() which handles this automatically.

Requires the later package.

Deployment

nanonext implements the _server.yml standard for R server frameworks, via the internal launch_server() function. This allows a deployment platform to launch a server without any knowledge of the package internals, given a _server.yml file at the root of the deployment:

engine: nanonext
constructor: server.R
options:
  host: 127.0.0.1
  port: 8080

constructor is an R file whose final expression evaluates to a handler or list of handlers for this function. A complete example ships with the package at system.file("examples", "server-yml", package = "nanonext").

See vignette("v04-web", package = "nanonext") for the full specification of the supported fields.

Examples

if (FALSE) { # interactive() && requireNamespace("later", quietly = TRUE)
# Simple HTTP server
server <- http_server(
  url = "http://127.0.0.1:8080",
  handlers = list(
    handler("/", function(req) {
      list(status = 200L, body = "Hello, World!")
    }),
    handler("/api/data", function(req) {
      list(
        status = 200L,
        headers = c("Content-Type" = "application/json"),
        body = '{"value": 42}'
      )
    })
  )
)
server$start()
# Run event loop: repeat run_event_loop(1000)
server$close()

# HTTP + WebSocket server
server <- http_server(
  url = "http://127.0.0.1:8080",
  handlers = list(
    handler("/", function(req) {
      list(status = 200L, body = "<html>...</html>")
    }),
    handler_ws("/ws", function(ws, data) {
      ws$send(data)  # Echo
    }, textframes = TRUE)
  )
)

# Multiple WebSocket endpoints
server <- http_server(
  url = "http://127.0.0.1:8080",
  handlers = list(
    handler_ws("/echo", function(ws, data) ws$send(data)),
    handler_ws("/upper", function(ws, data) ws$send(toupper(data)), textframes = TRUE)
  )
)

# HTTPS server with self-signed certificate
cert <- write_cert(cn = "127.0.0.1")
cfg <- tls_config(server = cert$server)
server <- http_server(
  url = "https://127.0.0.1:8443",
  handlers = list(
    handler("/", function(req) list(status = 200L, body = "Secure!"))
  ),
  tls = cfg
)
server$start()

# Send async request and run event loop
aio <- ncurl_aio(
  "https://127.0.0.1:8443/",
  tls = tls_config(client = cert$client),
  timeout = 2000
)
while (unresolved(aio)) run_event_loop(1000)

aio$status
aio$data

server$close()
}