Asynchronous Messaging
To communicate with each other asynchronously, Uniface components can send asynchronous messages (often known as postmessages). Components can send messages to other components running in the same Uniface client process, in other client processes, and in shared Uniface Server processes. Messages sent between different processes are transported via the Uniface Router.
Asynchronous messages can be sent in several ways:
- In ProcScript, using the postmessage ProcScript statement. For more information, see postmessage .
- In a 3GL component, using the API function upostmes(). For more information, see upostmes.
- On Windows, using the Message API Utility, either from the command line or using an ActiveX component. For more information, see Message API Utility.
Note: Parameters in the postmessage and the upostmessage() commands are similar but not the same, and different elements are mandatory.
Dispatching Asynchronous Messages
The way that asynchronous messages are dispatched depends on where the sending and receiving components are running.
When the message is sent by a component running in a client application:
- If the receiving component is in the same process, the message is placed in the Uniface message queue and delivered to that component when the script module or keystrokes are finished.
- If the receiving component is running in a different application or process, the message is first sent to the Uniface Router, which then dispatches it to the specified target application.
Communication is always asynchronous, regardless of whether the messages are handled in-process or by the Uniface Router.
When the asynchronous message is sent from a component running in a Uniface Server:
- If the receiving component is running in the
same
userver
process, the message is converted to a synchronoussend
message. 1 - If the receiving component is running in a different client or server process, the message is sent via the Uniface Router, just as it is when the sending component is running in a client application.
For messages handled by the Uniface Router, the target application or Uniface Server must be registered with the Uniface Router. If not, the messages are queued in the Uniface Router until the application does register and are then delivered. The Uniface Router does not start a Uniface Server process to receive a message. If the Uniface Router is stopped before the application registers, the messages are discarded and lost.
Note: Exclusive servers are not registered with the Uniface Router, so they cannot receive asynchronous messages.
The target application is identified by a
combination of user name and UST (Uniface server name). For Uniface clients, the combination of
user name and UST is unique. For shared servers, a UST represents a group of servers, so you need
to ensure that the combination is also unique, otherwise the message may go to the wrong server. A
simple way to ensure this is to specify /max=1
in the UST definition in the
Uniface Router's assignment file. For more information, see /max.
Receiving Asynchronous Messages
When the message is received by the target application, a receiveMessage trigger is fired:
- If the receiveMessage trigger of the component contains ProcScript, this trigger is activated.
- If the component-level trigger is empty, or if the specified target instance is not found, the receiveMessage trigger of the application (as defined in the instance path) is activated.
- 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 is desired, it must be explicitly programmed in the receiveMessage trigger.
For more information, see trigger receiveMessage .
Registering with the Uniface Router
Components in different applications or running on a remote server, are identified by both the instance path and the instance name. The receiving application process must be registered with the Uniface Router, which handles message transport.
Uniface clients that wish to receive messages from remote processes, must register explicitly with the Uniface Router. Uniface Servers that are started manually must also register with the Uniface Router.
A client or server process can be registered with the Uniface Router in several ways:
- Using the /dnp or /ust command line switches, or both.
- Using the $DNP path in the [PATHS] section of the client assignment file.
- Defining the UST of a Uniface Server in the
[SERVERS] section of the Uniface Router assignment file.
The Uniface Router can automatically start these servers and when it does, it automatically appends the /dnp switch. The Uniface Server registers with the Uniface Router to let it know that the startup was successful, that it is available to handle client requests, and that it can receive asyncrhonous messages.
For more information, see Registering Clients with the Uniface Router and Configuring the Uniface Router.
Configuring the Uniface Uniface Router for Asynchronous Messages
The Uniface Router is responsible for transporting asynchronous messages between Uniface components. For each message arriving at the Uniface Router, it makes a new network connection (TCP or TLS) and a new thread to handle that connection.
The default delivery mechanism in the Uniface Router assumes that a message can be forwarded to an application right away, so the resources used by the connection and handling thread are quickly released. Sometimes messages cannot be immediately dispatched, perhaps because the target server is busy for a long time and cannot read its network connection. In this case, the Uniface Router may run out of system resources and not be able to start new threads to handle incoming connections.
For such situations, it may be appropriate to use the $USE_PMQ assignment setting, causing the Uniface Router to create a queue for each target application. Messages are deposited in the queue and the connection and handling thread are quickly released. Messages are then forwarded from the queue to the target application at the rate that it can read them. For more information, see $USE_PMQ.
If there is a high volume of messaging, many TCP
sockets may end up in the TIMED_WAIT
state. Eventually the system may run out of
sockets and all new network communication will stop until more sockets become available. This effect
can be mitigated by using the setting USYS$TCP_PARAMS =
nl
. This is the no linger
option of the TCP connector
and ensures that sockets close instantly without going to the TIMED_WAIT
state.
For more information, see nl.
Broken DNP Connection in Clients
When a network connection fails, a client automatically tries to re-register its $DNP path with the Uniface Router.
If the Uniface Router is unaware of the failure,
it repeatedly returns error -23
(DuplicateUST) until it is informed that the
connection has been lost, because it already considers the $DNP path to be in
use.