Message in the OOCSI system
OOCSI is built on messages. All data in the OOCSI system is packaged conveniently into messages. Here you can find out all about sending and receiving messages in the system, from one-to-one communication to send-receive sequences and braodcasting to a whole group of OOCSI clients.
What’s in a message
Message contain standard data items like the sender, recipient, timestamp, and channel, and then variable data items that form the “payload”, the actual content of a message. While the standard items are filled in and handled by the platform, the variable data items are completely left to the user. You can choose to transmit very simple data, like yes/no (true/false) boolean values, numbers or text strings. You can also send composite data objects that contain lists of similar items or collections of diverse data.
Keys and values
Every piece of data in a message has a key, a name, and then the value, the actual data. We use keys in OOCSI messages to make clear what the transmitted data is about. If a client is sending 145 the recipient should immediately know that this is, for instance, a color component value or a distance measurement. The key would in this case say “color_R” for the value of the red color component, or “distance_mm” for a distance value with the unit millimeter. Naming keys and adding units and other meaning is completely left to the user, but we have found that being consistent about transmitted data helps enormously in creating systems with OOCSI.
Keys and values always come in pairs and you need the key to extract the value (for the key) from the message. If you don’t know the key, all client libraries have a way to list all keys in a message. There is not really more to understand about messages: sender and recipient are given, the message has a timestamp when it was processed by the server or broker, and then there are key-value pairs that contain the actual data.
Message features
Sending and receiving of messages is the basic interface for OOCSI. All clients support this functionality and that makes a message also a great interface for higher-level features that the server adds on top of the basic communication, such as message delays, scheduled dispatches, and retained channel state.
Delayed messages
The message feature delay allows you to postpone the dispatch of a message by n seconds. When a client sends a message with the _DELAY attribute, the server temporarily stores the message and dispatches it only after the delay duration has elapsed.
sequenceDiagram
autonumber
participant Pub as Publisher
participant Server as OOCSI Broker (Timer Queue)
participant Sub as Recipient / Subscriber
Pub->>Server: send("alerts", {msg: "Stretch break!", _DELAY: 30})
Note over Server: Enqueue message & start 30s countdown...
Note over Server: 30 seconds elapse!
Server->>Sub: Dispatch {"msg": "Stretch break!"}
Key rules for delayed messages:
- Relative delay: Provide the delay in seconds using the key
_DELAY. For example, use3600for 1 hour or86400for 1 day (maximum delay is 365 days). - Delivery guarantee: The message will be delivered even if the recipient client has not yet connected at the time of sending, or if the sender disconnects immediately after sending.
- Replacement per recipient: The server tracks delayed messages by
sender:recipient. If the same sender sends another delayed message to the same recipient before the first one fires, the newer message replaces the earlier pending one.
// Java / Processing
oocsi.channel("alerts").data("message", "Time to stretch!").data("_DELAY", 30).submit();
# Python
oocsi.send("alerts", { "message": "Time to stretch!", "_DELAY": 30 })
// JavaScript (oocsi-web.js)
OOCSI.send("alerts", { message: "Time to stretch!", _DELAY: 30 });
// ESP32 (Embedded C++ / Arduino)
oocsi.newMessage("alerts");
oocsi.addString("message", "Time to stretch!");
oocsi.addInt("_DELAY", 30);
oocsi.sendMessage();
Scheduled messages
In addition to relative delays, OOCSI supports scheduling messages for a specific calendar date and time using _SCHEDULE. Provide a timestamp string formatted as "yyyy-MM-dd HH:mm:ss". If the timestamp is in the future, the server holds the message and dispatches it when that moment arrives.
// Java / Processing
oocsi.channel("reminders").data("task", "Morning briefing").data("_SCHEDULE", "2026-09-20 09:00:00").submit();
# Python
oocsi.send("reminders", { "task": "Morning briefing", "_SCHEDULE": "2026-09-20 09:00:00" })
// JavaScript (oocsi-web.js)
OOCSI.send("reminders", { task: "Morning briefing", _SCHEDULE: "2026-09-20 09:00:00" });
// ESP32 (Embedded C++ / Arduino)
oocsi.newMessage("reminders");
oocsi.addString("task", "Morning briefing");
oocsi.addString("_SCHEDULE", "2026-09-20 09:00:00");
oocsi.sendMessage();
Retained messages
Retained messages allow you to “pin” a message to a channel on the server. Whenever a new client subscribes to that channel, the server immediately delivers the retained message to the newcomer. This is ideal for sharing the latest system state, device configurations, or sensor readings with clients that connect late or devices that frequently enter deep sleep to conserve battery.
sequenceDiagram
autonumber
participant Pub as Publisher
participant Server as OOCSI Broker (Retained Cache)
participant LateSub as Late Subscriber
Pub->>Server: send("room_status", {temp: 21.5, _RETAIN: 600})
Note over Server: Store latest state in cache (valid for 600s)
Note over LateSub,Server: 5 minutes later...
LateSub->>Server: subscribe("room_status")
Server->>LateSub: Deliver cached {temp: 21.5} immediately!
Key rules for retained messages:
- Duration: Set the retention duration in seconds with
_RETAIN. The maximum retention time supported by the server is 2 days (48 hours / 172,800 seconds). - Clearing a retained message: To evict/delete a retained message from a channel, send a message containing
_RETAIN: 0. - Non-destructive normal traffic: Regular messages sent to the channel without
_RETAINare delivered normally and do not wipe or overwrite the stored retained message. - Channel preservation: Even if all clients leave a channel, the channel is kept alive on the server for as long as its retained message remains valid.
// Java / Processing
// Pin message for 10 minutes (600 seconds)
oocsi.channel("room_status").data("occupied", true).data("temp", 21.5).data("_RETAIN", 600).submit();
// Clear the retained message explicitly
oocsi.channel("room_status").data("_RETAIN", 0).submit();
# Python
# Pin message for 10 minutes (600 seconds)
oocsi.send("room_status", { "occupied": True, "temp": 21.5, "_RETAIN": 600 })
# Clear the retained message explicitly
oocsi.send("room_status", { "_RETAIN": 0 })
// JavaScript (oocsi-web.js)
// Pin message for 10 minutes (600 seconds)
OOCSI.send("room_status", { occupied: true, temp: 21.5, _RETAIN: 600 });
// Clear the retained message explicitly
OOCSI.send("room_status", { _RETAIN: 0 });
// ESP32 (Embedded C++ / Arduino)
// Pin message before entering deep sleep
oocsi.newMessage("room_status");
oocsi.addBool("occupied", true);
oocsi.addFloat("temp", 21.5);
oocsi.addInt("_RETAIN", 600);
oocsi.sendMessage();
// Clear the retained message explicitly
oocsi.newMessage("room_status");
oocsi.addInt("_RETAIN", 0);
oocsi.sendMessage();