Skip to main content
rb.net sends HTTP requests, serves HTTP and WebSocket on a port of this computer, connects to WebSocket servers, and sends and receives UDP datagrams. A script reaches for it to call a web API, or to take commands from another program or machine. Needs: the net permission, which the client calls and ws_connect also accept as net:<host> entries; a coroutine for the client calls (get, post, put, patch, delete, head and request), so call them inside rb.run or rb.async (see Where code runs). This script posts JSON to an API and logs the reply, or the status when the request did not succeed:

HTTP client

options is { headers = { [name] = value }, timeout = ms }. rb.net.request takes { method, url, body?, headers?, timeout? } with method GET, POST, PUT, PATCH, DELETE or HEAD. Without timeout a request gives up after 30 seconds. The response is { status, body, headers } for any status; check status, since a 404 or 500 does not raise. body holds the response bytes exactly, so a PNG or a zip arrives intact; write it with rb.file.write. A body that is not UTF-8 makes rb.json.parse raise, so check status and the Content-Type header first. Request bodies are sent byte for byte as well. Binary bodies need min_sdk=3.18.0. Outside a coroutine a client call raises Net.Get() must be called inside Run() (with the call’s own name). A failed request raises HTTP request failed: <reason>. To build the body from a table, pass it through rb.json.stringify.

rb.net.listen

rb.net.listen(port: number, handler: (request: HttpRequest) -> HttpResponseSpec | string, options: { host: string? }?) -> ServerHandle Serves HTTP on 127.0.0.1:<port>, reachable only from this computer. A third argument { host = "0.0.0.0" } binds every interface so other machines can connect, and any other IP address binds that one; the host option needs min_sdk=3.18.0. host must be an IP address; "localhost" raises Net.Listen(): host 'localhost' is not an IP address. The server has no authentication, so check a token in the request before acting on it when it listens beyond this computer. The handler receives { method, path, body, headers } and returns { status?, body?, headers? } (status defaults to 200) or a string sent as a 200 body. Handlers run one request at a time per server; see the server dispatch row in Limits. A request unanswered after 30 seconds gets 504 with body Handler timeout. A second listen on a port this script already serves raises Port <n> already in use. A port another program holds, or an address this computer does not have, does not raise: the handle comes back, but nothing is served, and the failure is written to Rebind’s own log. The ServerHandle has port and stop. The handler is a plain call, not a coroutine: build the response at once, and start anything that waits with rb.run before returning. An uncaught error in the handler stops the script, so wrap parsing in pcall. path includes the query string, such as /press?key=F5, and header names keep the case the client sent. Returning nothing sends 200 with an empty body. A targeted script answers only while it is active; requests that arrive while it is inactive wait and get 504 after 30 seconds.

rb.net.ws_listen

rb.net.ws_listen(port: number, handlers: WsListenHandlers, options: { host: string? }?) -> WsServerHandle Serves WebSocket on 0.0.0.0:<port>, reachable from the network. A third argument { host = "127.0.0.1" } binds one address instead. There is no built-in rate limiting or authentication, so check a token before acting on a message. Handlers, all optional: client is a WsClient with an id. A message or frame larger than 64 MiB drops the connection. An error in a handler is logged to the script’s Logs, and the server keeps running. host must be an IP address; "localhost" raises Net.WSListen(): host 'localhost' is not an IP address. A second ws_listen on a port this script already serves raises WS port <n> already in use, and a port held elsewhere fails as with listen. For timing on the remote-control path, see Remote control.

rb.net.ws_connect

rb.net.ws_connect(url: string, handlers: WsConnectHandlers) -> WsConnectHandle Connects to a ws:// or wss:// URL; TLS trusts the standard web root certificates. Handlers on_open(), on_message(payload, is_binary) and on_close() are optional. A failed connection runs on_close without on_open. Up to 3 redirects are followed, none under net: entries.

rb.net.udp_listen

rb.net.udp_listen(bind_ip: string, port: number, handler: (data: string, ip: string, port: number) -> ()) -> UdpHandle Binds a UDP socket to the address given, so "127.0.0.1" stays on this computer. Port 0 picks a free port, readable from socket.port. The handler gets each datagram’s bytes and the sender. Datagrams of 2,048 bytes or more are dropped. An address that is not an IP raises Net.UDPListen: invalid bind address '<ip>'; one that cannot be bound, or a taken port, raises Net.UDPListen: could not bind <ip>:<port>: <reason>. A handler error is logged to the script’s Logs, and the socket keeps running. socket:send_to(ip, port, bytes) sends from the bound address and returns false when the send fails or the socket is stopped.

rb.net.local_ip

rb.net.local_ip() -> string? This computer’s IPv4 address on its default route, or nil. It sends nothing. It needs bare net; net:<host> entries do not grant it.