In Java applications it is common to use listeners to receive callbacks from other components. However, we also need a method to communicate globally between decoupled components, such as between a Java application and a browser-based UI, between two Java applications, between separate Java nodes. To enable decoupled and reliable communication, KOS provides the MessageBroker.
The MessageBroker uses the publish-subscribe pattern, where senders (publishers) send messages categorized by message topics rather than sending messages directly to receivers (subscribers). Subscribers can subscribe to specific message topics. This results in a one-to-many distribution of messages. The diagram below illustrates the entire system:
Message Broker: One-to-Many Message Distribution

Message Topics
In KOS messages are topic based. Topics are hierarchical, filesystem path style strings. For example, messages related to the state of a door might use topics such as: door/open and door/close.
Topics are delivered over WebSocket using URL paths, for example http://{URL}:{PORT}/api/app/{appID}/door/open. Note that the paths include the application ID, which is one of the reasons applications IDs should be carefully chosen when creating a new application.
This is how a class may autowire the MessageBroker
and send messages
Subscribers can listen to individual topics or take advantage of the hierarchical structure by using wildcards to subscribe to an entire category of topics:
When wildcards are used, the MessageData object received with every message provides both the topic the publisher used when sending the message (topic) and the topic pattern used when subscribing (subscription). This allows subscribers to distinguish between different child topics.
Message Body
In addition to the required topic, messages may also contain an optional body, which can be any JSON serializable Java object, and optionally use a JSON view. Publishers send objects, and the broker automatically serializes them to JSON.
On the Java side, subscribers can receive:
A raw JSON body, which is useful when subscribing to wildcard topics
A deserialized Java object, if the class is specified in the subscription
For example, we might send a message with data describing the state of the door, containing the door’s location (“front”, “back” or “garage”) and whether it is open (true or false):
Receiving the message
Sessions
When subscribing, a session object is required. Sessions act as book keeping keys that track subscription, prevent duplicate subscriptions, and allow bulk unsubscription. The specific type of the session object does not matter. A common pattern is for an application to use the Application object as a session for all subscriptions. When the application unloads, it can simply unsubscribe the application object to automatically clear all associated subscriptions.
Sessions can also be used to exclude a publisher session from receiving its own messages. So, in this case “mySession” will not receive this message. Note, the last null argument indicates that no JSON view is used.
Subscribers and Callbacks
Subscribers must implement the MessageBrokerCallback interface OR use a lambda expression. The callback receives a MessageData object.
MessageBroker Retention Policy
The MessageBroker does not store a persistent queue. Messages are delivered to all matching subscribers via the broker and then discarded. Most messages represent state changes that are only meaningful at the time that they are sent. As a result, there is no history of past messages and subscribers will not receive messages that were sent before they subscribed.
