Remote Procedure Call (RPC) is a communication mechanism that enables data exchange and invocation of methods between two processes. The processes can be on the same machine, on a local area network, or across the Internet.
RPC was initially developed as an extension to Open Software Foundation (OSF) RPC. With the exception of some of its advanced features, RPC is interoperable with other vendors' implementations of OSF RPC.
RPC includes the following major components:
- MIDL compiler
- Run-time libraries and header files
- Name service provider (sometimes referred to as the locator)
- Endpoint mapper (sometimes referred to as the port mapper)
In the RPC model, it is possible to formally specify an interface to the remote procedures using a language designed for this purpose. This language is called the Interface Definition Language (IDL). The Microsoft implementation is called the Microsoft Interface Definition Language (MIDL).
After an interface is created, it must be passed through the MIDL compiler, which generates the stubs that translate local procedure calls into remote procedure calls. Stubs are placeholder functions that make the calls to the run-time library functions, which manage the remote procedure call.
A client program calls what appear to be local procedures; the work of turning them into remote calls is done automatically. All code that translates data, accesses the network, and retrieves results is generated by the MIDL compiler and is invisible to the application.
The syntax of MIDL is based on the C programming language syntax. When a language concept in this description of MIDL is not fully defined, the C-language definition of that term is implied.
The MIDL design specifies two distinct files: the Interface Definition Language (IDL) file and the application configuration file (ACF). These files contain attributes that direct the generation of the C-language stub files managing the RPC. The IDL file contains a description of the interface between the client and the server programs. RPC applications use the ACF to describe the interface characteristics that are specific to the hardware and operating system that make up a particular operating environment.
The purpose of dividing this information into two files is to keep the software interface separate from characteristics that affect only the operating environment.
The IDL file specifies a network contract between client and server—that is, the IDL file specifies what is transmitted between the two. Keeping this information distinct from the operating environment information makes the IDL file portable to other environments. The IDL file consists of two parts: an interface header and an interface body.
The ACF specifies attributes that affect only local performance rather than the network contract. Microsoft RPC allows the combination of the ACF and IDL attributes in a single IDL file. It is also possible to combine multiple interfaces in a single IDL file (and its ACF).
The Distributed Component Object Model (DCOM) is a protocol that enables software components to communicate directly over a network. Previously called "Network OLE," DCOM is designed for use across multiple network transports, including Internet protocols such as HTTP. Based on the OSF's DCE-RPC specification, DCOM works with both Java applets and ActiveX components through its use of the Component Object Model (COM).
A COM network remote procedure call, or ORPC, is a DCE remote procedure call (DCE RPC) with a Request packet that conforms to the specification for such calls.
In an ORPC, the object ID field of the invocation header contains an interface pointer identifier (IPID). An IPID is a 128-bit identifier that represents an interface on an object in a particular server. As it is passed into the object ID fields of a DCE RPC, the static type of an IPID appears as a UUID. However, IPIDs are scoped not globally, but only relative to the machine on which the server is located (and which thus originally allocated them); IPIDs do not necessarily use the standard UUID allocation algorithm, but rather a machine-specific algorithm that can assist with dispatching.
In an ORPC, the interface ID field of the RPC header specifies the Interface ID (IID), and arguments are found in the body. However, when viewed from the DCE RPC perspective, an additional first argument is always present that is absent in the corresponding COM interface specification. This argument is of type ORPCTHIS, and it contains channel-specific data, acting as an ORPC-specific subheader for RPC packets. It is placed first in the body of the Request packet, above the actual ORPC arguments.
Similarly, in a reply to an ORPC (a DCE RPC Response packet) that is viewed from the DCE RPC perspective, an additional first return value is always present that is absent in the corresponding COM interface specification. This argument is of type ORPCTHAT, which, like ORPCTHIS, contains channel-specific data, acting as an ORPC-specific subheader for RPC packets. It is placed first in the body of the Response packet, above the actual ORPC return values.
An ORPCTHAT also can be present in a Fault packet. In the Connectionless (CL) Fault packet, it is placed 4 bytes after the 32-bit fault code that normally comprises the packet's entire body, thus achieving 8-byte alignment for the ORPCTHAT. The intervening padding bytes are currently reserved and must be zero. The packet body length is set to encompass the entire body of the Fault packet, including the ORPCTHAT. In the Connection-oriented (CO) Fault packet, the ORPCTHAT is placed in the standard location allocated for the stub data. If an ORPCTHAT is not present in a Fault packet of either form that results from an ORPC, no other data can be substituted in its location in the packet.
Server applications must select one or more protocol sequences to use when communicating with the client over the network. The choice of protocol sequences is network-dependent.
A server program might allow clients to connect using any protocol sequence that the network supports. To do this, it is necessary to invoke the RpcServerUseAllProtseqs function and pass RPC_C_PROTSEQ_MAX_REQS_DEFAULT as the first parameter. However, that is not the recommended approach. Rather, using the ncalrpc keyword for local calls and the ncacn_ip_tcp or ncacn_http keyword for remote calls is usually sufficient. Heterogenous networks are uncommon, and virtually all networks support TCP/IP.
To make a client restrict port allocation for dynamic endpoints to a specific port range, it is necessary to call RpcServerUseAllProtseqsEx instead. This function is specific to Microsoft RPC. It uses an extra parameter to pass port allocation control flags to the function.
Protocol sequences and endpoint information can be specified in a MIDL file when the server's interfaces are developed. If this is done, the server should use RpcServerUseAllProtseqsIf to register all of the protocol sequences and associated endpoint information provided in the IDL file. In addition, a corresponding RpcServerUseAllProtseqsIfEx function allows the server to pass port allocation–control flags.
To configure client and server programs to communicate with a specified protocol sequence, the server application should call RpcServerUseProtseq. For a complete list of Microsoft RPC protocol sequences, see RPC Functions on Microsoft Developer Network (MSDN).
Microsoft RPC also provides RpcServerUseProtseqEx to enable applications to select specific protocol sequences and control dynamic port allocation.
In addition to connection-oriented protocols, Microsoft RPC supports datagram (connectionless) protocols. Connection-oriented protocols are recommended. Datagram protocols have different feature sets than connection-oriented protocols and should be used only if a distributed system developer requires a feature or functionality available only in datagram protocols, such as:
- Datagrams support the User Datagram Protocol (UDP) and Internet Packet Exchange (IPX) connectionless transport protocols.
- Because it is not necessary to establish and maintain a connection, the datagram RPC protocol requires less resource overhead.
- Datagrams enable faster binding.
As with connection-oriented RPC, datagram RPC calls are by default nonidempotent; this means the call is guaranteed not to be executed more than once. However, a function can be marked as idempotent in the IDL file, telling RPC that it is harmless to execute the function more than once in response to a single client request. This allows the runtime to maintain less state on the server. Note that an idempotent call would be re-executed only in rare circumstances on an unstable network.
Datagram RPC supports the broadcast IDL attribute. Broadcast enables a client to issue messages to multiple servers at the same time. This lets the client locate one of several available servers on the network, or control multiple servers simultaneously. Note that the datagram broadcast is valid only within the local link, and usually does not cross routers. Broadcast calls are implicitly idempotent. If the call contains [out] parameters, only the first server response is returned. Once a server responds, all future RPCs over that binding handle are sent to that server only, including calls with the broadcast attribute. To send another broadcast, create a new binding handle or call RpcBindingReset on the existing handle.
Datagram RPC supports the [maybe] IDL attribute, which allows the client to send a call to the server without waiting for a response or confirmation. The call cannot contain [out] parameters. Calls that use the [maybe] calls are implicitly idempotent.