postmessage
Send a message from one component instance to another.
postmessage Destination,MessageId,MessageData
The Destination is of the form: {InstancePath:}InstanceName
The InstancePath is a network connector string:
NetworkMnemonic:
{ HostId
}{+
PortNumber}
|
UserName|
|
SymbolicName
Parameters
Parameter | Data Type | Description |
---|---|---|
Destination | String | Component instance that will receive the message. |
MessageId | String | Identifier for the message; must contain at least one non-blank character and be no more than 32 characters in total. |
MessageData | String | Message data sent with the message. The amount of data that can be sent is limited only by the memory resources available on the machines. |
InstancePath | String | Network connector string to the application running the target instance. If omitted, InstanceName is assumed to be in the current application. |
InstanceName | String | Name of an instance in the component pool. |
NetworkMnemonic | String | Three-letter connector code; usually
TCP |
HostId | String | Host name or IP address where the Uniface
Router is running. If omitted, the default is localhost ( the current machine).
The format of HostID determines the TCP protocol version to be used.
For more information, see Host Identification for TCP/IP and TLS. |
PortNumber | String | Port number on which the Uniface Router is
listening. If omitted, the default value is 13001 . |
UserName | String | User name under which the target application is running |
SymbolicName | String | Application identifier of an application registered with the Uniface Router |
Return Values
Value | Meaning |
---|---|
0
|
Message for InstanceName successfully placed in event queue; this does not mean that the message was actually delivered, only that it has been posted. |
-2
|
InstanceName is not correct: field or variable not found, or the string is not a valid instance name. |
-3
|
MessageId is not correct: field or variable not found, or the string is not a valid message identifier. |
Value | Error constant | Meaning |
---|---|---|
-16 through
-30 |
<UNETERR_*>
|
Errors during network I/O. |
-57
|
<UACTERR_NO_INSTANCE>
|
The named instance cannot be found in the component pool. For example, the name is an empty string (""). |
-159
|
<UACTERR_QUEUE>
|
Message could not be delivered to requested queue. |
-1105
|
<UPROCERR_INSTANCE>
|
The instance name provided is not valid. For example, the argument contains incorrect characters. For more information, see newinstance. |
-1107
|
<UPROCERR_PATH>
|
The path name is not correct or the path does not exist, for example, no assignment is found for the path. |
-1111
|
<UPROCERR_MESSAGE>
|
The message identifier is not valid; the field or variable was not found, or the string is not a valid message identifier. |
Use
Allowed in all component types.
Description
The postmessage statement sends a message to the specified component instance. It is typically used for asynchronous communication between component instances running in the same or in a different process. For example, it can be used for communication between master and detail component instances, or to a remote service.
Tip: If you need synchronous communication, you should use the activate statement.
Unlike the activate command, the postmessage command does not automatically create a new instance. The receiving instance must already exist; postmessage just posts the message to an event queue of the receiving instance.
Message Queuing and Dispatching
When a postmessage statement is encountered during ProcScript execution, the presence or absence of an InstancePath in the Destination parameter determines how the message is handled:
- If an InstancePath is
specified in the Destination, the message is first sent to the Uniface Router,
which then dispatches it to the specified component instance. This may be a remote component
running in a Uniface Server, a component running in a different application, or a component running
in the same application as the sending instance.
Communication is always asynchronous, regardless of whether the messages are handled in-process or by the Uniface Router.
- If InstancePath is omitted,
the receiving instance is assumed to be in the same process.
In a client application, the message is placed in the Uniface message queue and delivered to the target component instance when the current ProcScript module or keystrokes are finished.
In a Uniface Server, the message is converted to a synchronous
send
message. This is because the Uniface Server does not have the queuing functionality provided by the structure editor or the Uniface Router.Note: A UTIMER component running in a Uniface Server actually runs in a separate thread from the main
userver
process, so this behavior is not applicable. For more information, see UTIMER.
Note: When a postmessage statement is encountered in the Debugger, it is also treated synchronously, and the receiveMessage trigger of the target instance is activated immediately.
Message Reception
When the message reaches the top of the input queue, the receiveMessage trigger associated with receiving component is activated. This may be the component-level trigger or the application-level trigger.
- The component-level receiveMessage trigger of the target instance is activated if it contains ProcScript.
- The application-level receiveMessage trigger is activated if the component-level trigger is empty, or if the specified target instance is not found. The application is the one that is the target of InstancePath.
- If the application-level trigger is empty, there is no further action.
The sending instance does not automatically receive an acknowledgment that the message has been received. If this behavior is required, an acknowledgment must be explicitly returned by the receiving instance. For example:
trigger receiveMessage postmessage $msginfo("SRC"),"MSG001", %\ "Reply to sender: message received." end; receiveMessage
Message Content
When a receiveMessage trigger is activated by
postmessage, the $result ProcScript function contains the
string "message"
and the function $msginfo contains
MessageId, MessageData, and other information about the
message.
The information returned in $msginfo is available using the individual functions $instancename, $instancepath, $msgdata, $msgdst, $msgid, and $msgsrc. For more information, see $msginfo.
Communicating Between Master List and Detail Forms
A common construction in client applications is a parent component that displays a list of records, which has child components the enable the user to create new records or update existing ones. In the following example, the parent component (RCP_LIST) can have multiple child component instances of RCP_UPDATE (and RCP_NEW).
When a store is performed in one of the child instances, it uses postmessage to notify RCP_LIST that the recipe has been updated:
; RCP_UPDATE component trigger store store if ($status <0) message $text(1500) rollback commit else if ($status = 1) message $text(1723 else commit if ($status < 0) rollback commit else message $text(1805) ; Statements added to default store trigger: postmessage "RCP_LIST", $componentname, RCP_NR.RECIPES setformfocus "RCP_LIST" endif endif endif end; store trigger
- Send a message to RCP_LIST with the name of the current component as MessageId, and the primary key of the updated record (RCP_NR.RECIPES) as the MessageData.
- Return focus to the list of recipes so that the user can quickly select another to edit.
The receiveMessage trigger of RCP_LIST handles messages from the instances and updates the list of recipes:
; RCP_LIST component trigger receiveMessage RCP_NR = $msgdata if ( $msgid = "RCP_UPDATE" ) reload/nolock "RECIPES" endif if ( $msgid = "RCP_NEW" ) retrieve/x "RECIPES" endif if ( $msgid = "RCP_UPDATE" | $msgid = "RCP_NEW") sort "RECIPES", "RCP_NAME:A" retrieve/o "RECIPES" endif end ; receivemMessage
- Assign the record number provided in the message data to the RCP_NR field to use as the search profile.
- If the sender was an instance of RCP_UPDATE, RPC_LIST, reload the data
- If the sender was an instance of RCP_NEW, retrieve the new data
- In either case, sort the data and make the updated or new occurrence the current one