(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
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
procedures described below.
Return the transaction ID (“xid” for short) of call.
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.4, 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.,
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-server and 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
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
invocation). This object can be queried with the procedures described
#t if obj is a
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 in The GNU Guile Reference Manual).
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.
#t if obj is an I/O manager.
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;
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
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
&rpc-connection-lost-error is raised.
serve-one-stream-request except that the RPC is to be
handled in an asynchronous fashion.
Concretely, the procedure handler passed to
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