# Parse a valid IPC message
raw <- '{"id":"msg_001","type":"get_data","version":"1.0","payload":{},"timestamp":1234567890}'
msg <- RDesk::rdesk_parse_message(raw)
msg$type
#> [1] "get_data"This document defines the standard JSON envelope used for all communication between the R backend and the HTML/JS frontend in RDesk applications.
Every message sent across the native IPC bridge (WebView2 to stdin/stdout) must be a JSON object with the following structure:
{
"id": "msg_abc123",
"type": "action_name",
"version": "1.0",
"payload": {
"key": "value"
},
"timestamp": 1742123456.789
}id: A unique string identifier for the
message (e.g., for tracing or request/response correlation).type: The internal name of the message
or action. This triggers handlers on the receiving end.version: The version of the message
contract (currently “1.0”).payload: A JSON object containing the
actual data for the message.timestamp: Seconds since the Unix
epoch (including decimal fractions).When sending from R to the UI, use app$send():
RDesk automatically wraps your payload in the standard envelope before transmission.
When sending from the UI to R, use rdesk.send():
The rdesk.js library automatically constructs the
envelope with a unique ID and current timestamp.
The parser rdesk_parse_message() is designed to be
defensive. It will return NULL if: 1. The input is not
valid JSON. 2. The envelope is missing required fields
(type or payload).
In these cases, a warning() is emitted with the specific
failure reason.
If you are building custom extensions or handlers, always check for
NULL before processing:
When using async(), the result is automatically sent
back to the UI as a message of type
<original_type>_result.
For example:
| R registers | JS sends | JS receives |
|---|---|---|
on_message("filter_cars", async(...)) |
rdesk.send("filter_cars", payload) |
rdesk.on("filter_cars_result", fn) |
on_message("run_model", async(...)) |
rdesk.send("run_model", payload) |
rdesk.on("run_model_result", fn) |
This convention means the JS developer always knows which event to listen for without reading the R code. It is consistent and predictable.
If you need a different result type, use rdesk_async()
directly (Tier 2) and call app$send() explicitly in your
on_done callback.