RemoteNotification

RemoteNotification is a sample that illustrates how to send notifications across task boundaries using MRemoteCallerNotifier and MRemoteDispatcherNotifier.

You should be familiar with Communications (RPC in particular) before reviewing this sample. The overall structure is very similar to the RPC sample.

This sample doesn't use any custom interests or notifications, so in other respects it is most similar to BasicNotification.

Running the sample

Execute RemoteNotificationSApp. It will launch the server if needed. The client makes calls on the server through its local representative, and the server issues notifications back through the receiver. Owing to the asynchronicity of the client and server, by the time the receiver receives the first notifications, the server has already reached its final value. As the receiver reports the "current" value for each notification, the value is always the same.

Files and classes

MSenderProtocol

MSenderProtocol is defined in SenderProtocol.h and SenderProtocol.C. It defines the abstract protocol that RPC and TReceiver rely upon.

TSender

TSender is defined in Sender.h and Sender.C. It is designed to be used either standalone or on the dispatcher side of the RPC connection. Here are the principal features of TSender:

1) It derives from MSenderProtocol and provides a concrete implementation for its abstractions.

2) It derives from MDelegatingNotifier, so that when used on the dispatcher side of the RPC, it can use the MDispatcherNotifier. For convenience, it implements GetNotifier to create an instance of TNotifier, if it has not already been told to use another notifier. TSender class could be used as is in the previous samples without other changes to them. The flag fOwnsNotifier is used to indicate whether the notifier is one that was set "from outside," or one it created for its own use.

3) It defines SetNotifier so that clients can tell it to use a particular notifier. Note that this is not protocol of MDelegatingNotifier (GetNotifier is), but makes it convenient for TSenderDispatcher to use an instance of TSender as its implementation.

4) It implements GetValueChangedInterest to construct an interest with the notifier returned by GetNotifier, because it is no longer itself a notifier.

TReceiver

TReceiver is defined in Receiver.h and Receiver.C. It is the same as the TReceiver in BasicNotification, except that it connects to an MSenderProtocol instead of a TSender.

TSenderCaller

TSenderCaller is defined in SenderCaller.h and SenderCaller.C. Here are the principle features of TSenderCaller:

1) It derives from MRemoteCaller for RPC.

2) It derives from MRemoteCallerNotifier so that it can relay notifications sent by the MRemoteDispatcherNotifier on the other side of the RPC connection to receivers that have connected to it.

3) It derives from MSenderProtocol and provides a concrete implementation for its abstractions.

4) In its constructor, it sets the MRemoteCallerNotifier to use the MRemoteCaller it has mixed in with. It calls MRemoteCallerEnable, which RPC requires of classes derived from MRemoteCaller.

5) It implements GetValue and SetValue to use RPC to stream the requests and data to the dispatcher.

6) It uses a monitor lock so that the same sender caller may be used by multiple threads (in this example, the main thread and the receiver thread).

TSenderDispatcher

TSenderDispatcher is defined in SenderDispatcher.h and SenderDispatcher.C. Here are the principle features of TSenderDispatcher:

1) It derives from MRemoteDispatcher for RPC.

2) It derives from MRemoteDispatcherNotifier so that notifications sent from it are relayed to the MRemoteCallerNotifier on the other side of the RPC connection.

3) In its constructor, it adopts an instance of TSender. It uses the fact that TSender is now an MDelegatingNotifier, and has defined protocol to set the notifier it uses, to tell the adopted TSender to use it as its notifier. Thus, when TSender calls Notify, the MRemoteDispatcherNotifier is used, and notifications pass to the MRemoteCallerNotifier on the other side.

4) It implements FwdAddRemoteInterest and FwdRemoveRemoteInterest to forward these calls to the MRemoteDispatcherNotifier. In the constructor, it uses standard RPC boilerplate to register these requests with the MRemoteDispatcher.

5) It implements SetValueStub and GetValueStub to extract the requests and data from the stream and forward these calls to the TSender implementation. In the constructor, it uses standard RPC boilerplate to register these requests with the MRemoteDispatcher.

Notes:

All the standard RPC cautions apply. Be sure to call RemoteCallerEnable in the caller, properly register the requests in the dispatcher, call the MRemoteCallerDeclarationsMacro in the private section of the TSenderCaller passing the class name of the dispatcher, and set up your transports properly. For more information on this, see Capter 4, "Communications Access" in "OS Services" and relevant samples.

Asynchronous communication, as a result of RPC, means that the receiver can receive notifications some time after the notifications were sent. In this example, by the time the TReceiver can process any notifications, the caller has been changed multiple times, so when the receiver tries to query the state of the sender, it is no longer the same as when the notifications were sent.

The notifications are received in a separate thread from the main thread. Both the main thread and the receiver thread use the same caller-- the main thread calls SetValue, and in the receiver thread the receiver uses the same caller to call GetValue. Each call uses the RPC mechanism, but it is an error (an exception will be thrown) to start an RPC call while another is still pending. So TSenderCaller contains a lock, and each call that uses RPC acquires a monitor on the lock before trying to do RPC. In this way the two threads are prevented from attempting RPC at the same time.

main() uses a delay to block this thread so that the thread that dispatches the notifications can run. Otherwise, the main thread might exit before all notifications have been received.


Click the icon to mail questions or corrections about this material to Taligent personnel.
Copyright©1995 Taligent,Inc. All rights reserved.