• Public
  • Public/Protected
  • All

Interface TopicControl

This feature allows a session to manage topics. It provides the following capabilities:

1) Adding and removing topics.
2) Missing topic notifications — listening for requests to subscribe to topics that do not exist thus allowing dynamic topic creation on demand.
3) Topic event listeners — listening for topic events, such as the number of subscribers to a topic changing from zero to greater than zero or from greater than zero to zero.


The Diffusion server stores data in topics. Each topic is bound to a topic path in the topic tree, and may have a current value. Sessions can subscribe to topics. Updates to topic values are broadcast to subscribing sessions. There are several types of topic. The topic type determines the type of the data values a topic publishes to subscribers.

Adding topics

Creating topics

The simplest way to create a topic is to call TopicControl.add, supplying a topic type. For example, to create a JSON topic bound to the topic path foo:

const result = session.topic.add("foo", diffusion.TopicType.JSON);

Success or failure is reported asynchronously through the CompletableFuture result.

The nature of a topic depends primarily on its topic type, but can be customized using topic properties. Some types of topic cannot be created without supplying mandatory topic properties. Topic properties can be supplied in a topic specification using add(topicPath: string, specification: TopicSpecification). Topic specifications can be created using new TopicSpecification(...) and further customized with builder methods. For example, to create a JSON topic bound to the topic path foo with the VALIDATE_VALUES property set to true:

// Create specification for JSON topics which validate update values on the server
const TopicSpecification = diffusion.topics.TopicSpecification;

var specification = new TopicSpecification(diffusion.topics.TopicType.JSON)
    .withProperty(TopicSpecification.VALIDATE_VALUES, "true");

See TopicSpecification for details of the available topic properties and their effects on the different types of topic.

Topic creation is idempotent. If addTopic(path, specification) is called and there is already a topic bound to path with a topic specification equal to specification, the call will complete normally with an TopicAddResult result that indicates that no topic has been added. However, if there is a topic bound to path with a different topic specification, the call will fail.

Removing topics

Topics can be removed using TopicControl.remove. Only those selected topics for which the caller has MODIFY_TOPIC permission will be removed, any others will remain.

Topics can also be automatically removed according to a removal criteria specified using the REMOVAL topic property.

Managing topic tree hierarchies

A topic can be bound to any path in the topic tree namespace. The only restriction is that two topics cannot have the same path. In the following example a topic can be created with the path A/B/foo even though there are no topics with path A or A/B:

topicControl.addTopic("A/B/foo", TopicType.JSON);

Topics bound to the paths A or A/B can be created later.

Topics can be removed without affecting the topics subordinate to them in the topic tree using TopicControl.remove providing a path topic selector. By using the // topic selector qualifier it is possible to remove a topic and all of its descendant topics, that is to remove whole topic tree branches.

Access control

To add or remove a topic, a session needs MODIFY_TOPIC permission for the topic path. When removing topics with a topic selector that matches more than one topic, only topics with paths for which the session has MODIFY_TOPIC permission will be removed.

To register a missing topic handler the session needs REGISTER_HANDLER permission.

Accessing the feature

This feature may be obtained from a session as follows:


// Get a reference to topic control feature
var topics = session.topics;


  • TopicControl




  • Add a topic to the server at a specific path. This returns a Result.

    The path should be a string. To express hierarchies, / can be used as a delimiter. This allows topics to be nested and grouped below each other. For example, session.topics.add('foo/bar'); creates the topic bar . A topic is not created at foo by this method.

    Each topic has a particular type, which constrains the kind of values that the topic will allow. This type can either be explicitly provided, or included as part of a TopicSpecification.

    Adding from topic type

    To directly specify the type of topic to create, provide a string path and a TopicType. Topics specified in this way are created with default topic properties, as described in TopicSpecification.

    Adding from topic specification

    TopicSpecifications allows the creation of topics of a particular type, along with additional properties that determine how the topic operates. For instance, you may wish to specify that a topic will validate values before publishing, or that it will only publish values instead of deltas.

    Operation results

    If the topic was added, or a topic already exists with the same path and specification, the operation will succeed. If there is a problem with adding the topic then the result will be rejected with an error.

    If any sessions have already subscribed to the same path that a topic is created for, they will receive a subscription event once the topic is added, and a value event with the initial value (if supplied).

    If the session is closed when calling this method, the returned result will be rejected.


    If the operation fails a TopicAddFailReason is provided. Adding a topic may fail because the session has insufficient permissions; a topic already exists at the specified path; or certain mandatory TopicSpecification properties were missing


    // Create a topic with a Topic Type
    session.topics.add('foo/binary', diffusion.topics.TopicType.BINARY);


    // Create a topic with a TopicSpecification
    const TopicSpecification = diffusion.topics.TopicSpecification;
    var specification = new TopicSpecification(diffusion.topics.TopicType.JSON, {
        TopicSpecification.VALIDATE_VALUES : "true"
    session.topics.add('foo/json', specification);


    // Handle the add topic result
    session.topics.add('foo/bob', diffusion.topics.TopicType.JSON).then(function(result) {
        if (result.added) {
            console.log('Topic added');
        } else {
            console.log('A compatible topic already exists');
    }, function(error) {
        console.log('Topic add failed: ', error);


    Returns Result<TopicAddResult>

    a Result for this operation


  • Register a MissingTopicHandler to handle requests for a branch of the topic tree.

    The provided handler is called when a client subscribes using a topic selector that matches no existing topics. This allows a control client session to be notified when another session requests a topic that does not exist.

    A control client can register multiple handlers, but may only register a single handler for a given topic path. See MissingTopicHandler.onRegister. A handler will only be called for topic selectors with a path prefix that starts with or is equal to topicPath . If the path prefix matches multiple handlers, the one registered for the most specific (longest) topic path will be called.

    If the session is closed or the handler could not be registered, the returned Result will call its failure callback, and the handler's MissingTopicHandler.onClose or MissingTopicHandler.onError method will be called.


    Returns Result<void>

    a Result for this registration


  • Remove one or more topics at the server.

    The topics to remove will depend upon the nature of the topic selector specified. If the selector does not have descendant pattern qualifiers (i.e. / or //), only those topics that exist at paths indicated by the selector will be removed and not their descendants. If a single / qualifier is specified, all descendants of the matching topic paths will be removed. If // is specified, all branches of the topic tree that match the selector (i.e topics at the selected paths and all descendants of the selected paths) will be removed.

    This function can take any number of arguments. Each argument can be a string or a TopicSelector. Alternatively, an array of strings and TopicSelectors can be passed as a single argument. At least one valid selector has to be specified.


    // Remove the topic at 'foo/bar', leaving descendants


    // Remove the topic at 'foo/bar' and all descendants


    • selector: Array<string | TopicSelector>

      the selector specifying the topics to remove

    Returns Result<TopicRemovalResult>

    a Result resolving to a TopicRemovalResult

  • Parameters

    Returns Result<TopicRemovalResult>