(rpc rpc server) module provides helpful facilities for
building an ONC RPC server. In particular, it provides tools to
decode RPC call messages, as well as an event loop mechanisms that
allows RPC calls to be automatically dispatched to the corresponding
<rpc-call>object that denotes the procedure call requested in call-msg (the result of an
(xdr-decode rpc-message port)operation). If call-msg is not an appropriate RPC call message, an error condition is raised.
The error condition raised may be either
The returned object can be queried using the
rpc-call-procedures described below.
Return the program, version or procedure number of call.
Return the credentials and verifier provided by the client for call. FIXME: As of version 0.3, this information is not usable.
The following procedures allow the description of RPC “programs”. Such descriptions can then be readily used to produced a full-blown RPC processing loop.
Return a new object describing the RPC program identified by number and consisting of the versions listed in versions.
Return a new object describing the RPC program version identified by number and consisting of the procedures listed in procedures.
Return a new object describing a procedure whose number is number, whose argument type is argument-xdr-type and whose result type is result-xdr-type (see XDR Type Representations). handler should be a procedure that will be invoked upon reception of an RPC call for that procedure.
If synchronous RPC processing is used, i.e., through
serve-one-stream-request, then handler is passed the decoded argument and should return a result type that may be encoded as result-xdr-type. If asynchronous processing is used, i.e., through
serve-one-stream-request/asynchronous, then handler is passed the decoded argument along with a continuation that must be invoked to actually return the result.
If one-way? is passed and is true, then the returned procedure is marked as “one-way” (see
make-one-way-rpc-call). For one-way procedures,
run-stream-rpc-serverand similar procedures ignores the return value of handler and don't send any reply when procedure number is invoked.
Once a program, its versions and procedures have been defined, an RPC server for that program (and possibly others) can be run using the following procedures.
Run a full-blown connection-oriented (i.e.,
SOCK_STREAM, be it
PF_INET) RPC server for the given listening sockets and RPC programs. sockets+rpc-programs should be a list of listening socket-RPC program pairs (where “RPC programs” are objects as returned by
make-rpc-program). timeout should be a number of microseconds that the loop should wait for input; when no input is available, idle-thunk is invoked, thus at most every timeout microseconds. If close-connection-proc is a procedure, it is called when a connection is being closed is passed the corresponding
While an RPC server is running over a stream-oriented transport such as
run-stream-rpc-server, its procedure handlers can get
information about the current connection and client:
This procedure returns a
<stream-connection>object describing the current TCP connection (when within a
run-stream-rpc-serverinvocation). This object can be queried with the procedures described below.
Return the I/O port (not the TCP port) for connection.
Return the IP address of the peer/client of connection (see Network Socket Address).
Return the RPC program object corresponding to connection.
For a complete RPC server example, Creating the Server.
run-stream-rpc-server mechanism is limited to servers
managing only RPC connections, and only over stream-oriented
transports. Should your server need to handle other input sources, a
more geneneral event handling mechanism is available. This works by
first creating a set of I/O managers and then passing
run-input-event-loop a list of I/O manager-file descriptor pairs
to actually handle I/O events.
Return an I/O manager. When data is available for reading, read-handler will be called and passed a port to read from; when an exception occurs on a port, exception-handler is called and passed the failing port.
Return, respectively, the exception handler and the read handler of manager.
Run an input event loop based on fd+manager-list, a list of pairs of input ports (or file descriptors) and I/O managers. I/O managers are invoked are invoked and passed the corresponding port when data becomes readable or when an exception occurs. I/O manager handlers can:
#f, in which case the port and I/O manager are removed from the list of watched ports;
- return a pair containing an input port and I/O manager, in which case this pair is added to the list of watched ports;
- return true, in which case the list of watched ports remains unchanged.
When timeout (a number of microseconds) is reached, idle-thunk is invoked. If timeout is
#f, then an infinite timeout is assumed and idle-thunk is never run. The event loop returns when no watched port is left.
The event loop provided by
run-input-event-loop should cover a
wide range of applications. However, it will turn out to be
insufficient in situations where tasks must be executed at specific
times, and where the interval between consecutive executions varies over
the program's lifetime.
Finally, a lower-level mechanism is available to handle a single incoming RPC:
Serve one RPC for program, reading the RPC from port (using the record-marking protocol) and writing the reply to port. If port is closed or the end-of-file was reached, an
serve-one-stream-requestexcept that the RPC is to be handled in an asynchronous fashion.
Concretely, the procedure handler passed to
make-rpc-procedureis called with two arguments instead of one: the first one is the actual procedure argument, and the second one is a one-argument procedure that must be invoked to return the procedure's result—in other words, procedure call processing is decoupled from procedure call return using continuation-passing style.