Module message exchange
Glossary Item Box
Introduction
A bpm’online module is an isolated software unit. It has no information about other bpm’online modules apart from the module name list from which is depends. See “Modular development principles in bpm'online” for more information about bpm’online modules.
Sandbox object is used for interaction between the isolated modules. One of the key sandbox mechanisms is module message exchange.
Modules can only communicate via messages. A module shall publish a message to communicate its status change to other bpm’online modules. If the module needs to receive messages about status change in other modules, it must be subscribed to these messages.
To interact with other bpm’online modules, the module must import the sandbox module as a dependency.
NOTE
It is not necessary to specify ["ext-base", "terrasoft", "sandbox"] base modules in dependencies if the module exports class constructor. Ext, Terrasoft and sandbox objects will be available as object properties after creating module class object: this.Ext, this.Terrasoft, this.sandbox.
Message registration
You need to register messages to implement module message exchange.
NOTE
Message registration is executed automatically if messages are declared in the messages module property.
sandbox.registerMessages(messageConfig) method is used to register module messages, where messageConfig is a module message configuration object.
Configuration object is a “key-value” collection, where every element is as follows:
"MessageName": {
mode: [Message operation mode],
direction: [Message direction]
}
“MessageName” is a collection element key that contains the message name. The value is a configuration object that contains the following properties:
- mode – message operation mode. Must contain Terrasoft.MessageMode (Terrasoft.core.enums.MessageMode) enumeration value.
- direction – message direction. Must contain Terrasoft.MessageDirectionType (Terrasoft.core.enums.MessageDirectionType) enumeration value.
Message exchange modes (mode property):
- Broadcast – message operation mode with a predefined number of subscribers. Corresponds to Terrasoft.MessageMode.BROADCAST enumeration value.
- Address – message operation mode when a message can only be processed by one subscriber. Corresponds to Terrasoft.MessageMode.PTP. enumeration value.
ATTENTION
There can be several subscribers in the address mode, but only one can process messages, usually it is the last registered subscriber.
Message direction (direction property):
- Publication (publish) – the module can only publish a message in sandbox. Corresponds to Terrasoft.MessageDirectionType.PUBLISH. enumeration value.
- Subscription (follow) – the module can only subscribe to a message, published from another module. Corresponds to Terrasoft.MessageDirectionType.SUBSCRIBE. enumeration value.
- Bidirectional – allows to publish and subscribe to the same message in different instances of the same class or within the same schema inheritance hierarchy. Corresponds to Terrasoft.MessageDirectionType.BIDIRECTIONAL. enumeration value.
Module message registration:
// Message configuration object collection. var messages = { "MessageToSubscribe": { mode: Terrasoft.MessageMode.PTP, direction: Terrasoft.MessageDirectionType.SUBSCRIBE }, "MessageToPublish": { mode: Terrasoft.MessageMode.BROADCAST, direction: Terrasoft.MessageDirectionType.PUBLISH } }; // Message registration. this.sandbox.registerMessages(messages);
ATTENTION
It is not necessary to register messages via the sandbox.registerMessages() method in the view model schemas. Declare the message configuration object in messages property (see "Messages. The "messages" property").
To reject message registration in a module, use sandbox.unRegisterMessages(messages) method, where messages – is a message name or a message name array. Message registration rejection:
// Single message registration rejection. this.sandbox.unRegisterMessages("MessageToSubscribe"); // Message array registration rejection. this.sandbox.unRegisterMessages(["MessageToSubscribe", "MessageToPublish"]);
Adding messages to module schema
You can also register messages by adding them to a module schema or via a designer (see “Module designer”).
To add messages to module schema:
1. On the [Structure] tab of the module schema designer select the [Messages] node, right-click and execute the [Add] command (Fig.1).
Fig. 1. Adding messages to the module schema structure
2. Set the necessary properties for the added message (Fig.2):
- [Name] – the message name that corresponds to the module configuration object key.
- [Direction] – message direction. Possible values: “Follow” (subscribe) and “Publish” (publish).
- [Mode] – message operation mode. Possible values: “Broadcast” and “Address”.
Fig. 2. Message properties
ATTENTION
It is not necessary to add messages to schema structure in view model schemas .
Message publication
sandbox.publish(messageName , messageArgs, tags) method is used to publish messages.
Method parameters:
- messageName – the string that contains the message name, for instance, "MessageToSubscribe".
- messageArgs – the object, passed as an argument to the message handler method in the subscription module. If there are no input parameters in the handler method, assign null value to messageArgs parameter.
- tags – tag array that allows to uniquely identify the message sending module. Usually, the [this.sandbox.id] value is used. Sandbox defines the message subscribers and publishers according to the tag array.
NOTE
Only the handlers that meet at least one tag will be run for the message published with the tag array. Messages, published without tags, will only be processed by subscribers without tags.
Message publication method:
// Message publication without tags or argument. this.sandbox.publish("MessageWithoutArgsAndTags"); // Message publication without a handler method argument. this.sandbox.publish("MessageWithoutArgs", null, [this.sandbox.id]); // Message publication with a handler method argument. this.sandbox.publish("MessageWithArgs", {arg1: 5, arg2: "arg2"}, ["moduleName"]); // Message publication with an arbitrary tag array. this.sandbox.publish("MessageWithCustomIds", null, ["moduleName","otherTag"]);
When you publish a message in the address mode, you can receive the result of its processing by the subscriber. To do this, the message handler method in the subscription module must return the corresponding result (see “Message subscription”). Message publication:
// Message declaring and registration. var messages = { "MessageWithResult": { mode: Terrasoft.MessageMode.PTP, direction: Terrasoft.MessageDirectionType.PUBLISH } }; this.sandbox.registerMessages(messages); // Message publication and receipt of the result of its processing by the subscription module. var result = this.sandbox.publish("MessageWithResult", {arg1:5, arg2:"arg2"}, ["resultTag"]); // Result display on the browser console. console.log(result);
When you publish a message in the broadcast mode, you can receive the result of its processing via the object, passed as an argument to the handler method.
// Message declaring and registration. var messages = { "MessageWithResult": { mode: Terrasoft.MessageMode.BROADCAST, direction: Terrasoft.MessageDirectionType.PUBLISH } }; this.sandbox.registerMessages(messages); var arg = {}; // Message publication and receipt of the result of its processing by the subscription module. // Add result property into the object of the subscription module handler method and populate it with the processing result. this.sandbox.publish("MessageWithResult", arg, ["resultTag"]); // Result display on the browser console. console.log(arg.result);
Message subscription
You can subscribe to a message using the sandbox.subscribe(messageName, messageHandler, scope, tags) method.
Method parameters:
- messageName – the string that contains the message name, for instance, "MessageToSubscribe".
- messageHandler – the handler method, run upon the message receipt. It can be either an anonymous function or a module method. A parameter, whose value must be passed upon the message publishing via the sandbox.publish() method can be indicated in the method definition.
- Scope – messageHandler handler method execution context.
- tags – tag array that allows to uniquely identify the message sending module. Sandbox defines the message subscribers and publishers according to the tag array.
Message subscription method:
// Message subscription without handler method arguments. // Handler method is an anonymous function. Execution context is the current module. //The getsandboxid() method must return the tag that corresponds to the published message tag. this.sandbox.subscribe("MessageWithoutArgs", function(){console.log("Message without arguments")}, this, [this.getSandBoxId()]); // Message subscription with a handler method argument. this.sandbox.subscribe("MessageWithArgs", function(args){console.log(args)}, this, ["moduleName"]); // Message subscription with an arbitrary tag. // It can be any tag out of the published message tag array. // The myMsgHandler handler method must be implemented separately. this.sandbox.subscribe("MessageWithCustomIds", this.myMsgHandler, this, ["otherTag"]);
The message handler method must return the corresponding result for a message in the address mode. Message subscription:
// Message declaring and registration. var messages = { "MessageWithResult": { mode: Terrasoft.MessageMode.PTP, direction: Terrasoft.MessageDirectionType.SUBSCRIBE } }; this.sandbox.registerMessages(messages); // Message subscription. this.sandbox.subscribe("MessageWithResult", this.onMessageSubscribe, this, ["resultTag"]); ... // The handler method is implemented in the subscription module. // args — object, passed upon message publication. onMessageSubscribe: function(args) { // Parameter change. args.arg1 = 15; args.arg2 = "new arg2"; // Obligatory return of result. return args; },
Asynchronous message exchange
Use callback function approach if the message handler method in subscription module generates the result asynchronously.
Message publication and result:
// Message publication without tags or argument. this.sandbox.publish("MessageWithoutArgsAndTags"); // Message publication without a handler method argument. this.sandbox.publish("MessageWithoutArgs", null, [this.sandbox.id]); // Message publication with a handler method argument. this.sandbox.publish("MessageWithArgs", {arg1: 5, arg2: "arg2"}, ["moduleName"]); // Message publication with an arbitrary tag array. this.sandbox.publish("MessageWithCustomIds", null, ["moduleName","otherTag"]);
Message subscription:
// Message subscription without handler method arguments. // Handler method is an anonymous function. Execution context is the current module. //The getsandboxid() method must return the tag that corresponds to the published message tag. this.sandbox.subscribe("MessageWithoutArgs", function(){console.log("Message without arguments")}, this, [this.getSandBoxId()]); // Message subscription with a handler method argument. this.sandbox.subscribe("MessageWithArgs", function(args){console.log(args)}, this, ["moduleName"]); // Message subscription with an arbitrary tag. // It can be any tag out of the published message tag array. // The myMsgHandler handler method must be implemented separately. this.sandbox.subscribe("MessageWithCustomIds", this.myMsgHandler, this, ["otherTag"]);
Module with a message:
Below is a module with message publication and subscription:
define("UsrSomeModule", [], function() { Ext.define("Terrasoft.configuration.UsrSomeModule", { alternateClassName: "Terrasoft.UsrSomeModule", extend: "Terrasoft.BaseModule", Ext: null, sandbox: null, Terrasoft: null, messages: { "MessageToSubscribe": { mode: Terrasoft.MessageMode.PTP, direction: Terrasoft.MessageDirectionType.SUBSCRIBE }, "MessageToPublish": { mode: Terrasoft.MessageMode.BROADCAST, direction: Terrasoft.MessageDirectionType.PUBLISH } }, init: function() { this.callParent(arguments); this.sandbox.registerMessages(this.messages); this.processMessages(); }, processMessages: function() { this.sandbox.subscribe("MessageToSubscribe", this.onMessageSubscribe, this); this.sandbox.publish("MessageToPublish", null, [this.sandbox.id]); }, onMessageSubscribe: function() { console.log("'MessageToSubscribe' received"); }, destroy: function() { if (this.messages) { var messages = this.Terrasoft.keys(this.messages); this.sandbox.unRegisterMessages(messages); } this.callParent(arguments); } }); return Terrasoft.UsrSomeModule; });
For more information
- Modular development principles in bpm'online
- Module types and their specificities
- Client view model schemas
- Messages. The "messages" property
- Bidirectional messages