Unlike an RPC launched module (see RPC Launched Modules (No Return Statement)), if the called module contains a return statement then it becomes a subroutine. When a subroutine executes, all other statements within the thread that is running the subroutine will not execute until the subroutine has returned. A subroutine called via the \RPCManager\Send() function is run on the RPC Manager's thread. This behavior ensures that only one RPC subroutine is ever running within an instance of VTS. This allows the RPC subroutine to access three important variables within the RPC Manager:
• CurSocketNode – This variable is the WorkstationNode object that exists for the workstation that issued the remote procedure call. A WorkstationNode exists for every workstation with which an instance of VTS can communicate, including the local workstation. Before support for multi-homed workstations was introduced, this variable referred to the SocketNode from which an RPC request had been received. Its name has not been changed in order to preserve compatibility with existing applications.
• CurSessionID – the opaque Session ID of the application instance that issued the RPC (see Session IDs).
• CurSourceAppGUID – the GUID of the application which issued the RPC (see section Cross-Application RPC).
Note: The contents of the above three variables are valid only for the duration of the execution of the RPC subroutine. When the RPC subroutine returns, these variables become invalid and then are set to new contents for the next RPC subroutine execution. If you wish to retain the contents of either of these variables prior to their reset, you must make a copy during execution of the RPC subroutine.
Execution of an RPC subroutine suspends all other RPC activity on the workstation executing the subroutine; therefore, if there is time-consuming work to be performed, it is recommended to have the RPC subroutine launch a worker module into an appropriate context, passing the contents of CurSocketNode and CurSessionID (if required) as parameters. For example:
{======================= SampleRPCLaunch ========================}
{ This subroutine is called via RPC and launches off a worker }
{ module to do some time-consuming work. }
{================================================================}
(
SomeParam { Parameter to the RPC subroutine };
DoTheWork Module;
)
Only [
If watch(1);
[
{*** Pass the CurSessionID & CurSocketNode to the launched module ***}
DoTheWork(SomeParam, \RPCManager\CurSocketNode,
\RPCManager\CurSessionID);
Return(0);
]
]
<
{============= SampleRPCLaunch\DoTheWork ====================}
{============================================================}
DoTheWork
(
SomeParam { Same as RPC subroutine };
ClientSocketNode { Client socket node at time of starting };
ClientSID { Calling client's session ID };
)
{ End of SampleRPCLaunch\DoTheWork }
>