Project 2 - Simple RPC

Client-Server Interfaces, Spring 2004


Table of Contents

Due Date

This assignment is due on Tuesday, 6 April, no later than 5:00 p.m.

See the assignment turn-in page (last modified on 9 February 2004) for instructions on turning in your assignment.

Background

Simple RPC (sRPC) is a combination of Sun's ONR RPC (in terms of software structure) and XML-RPC (in terms of everything else). However sRPC uses neither XDR nor XML, but rather a simple, text-based description of calls and data.

A single sRPC server implements a single service, which consists of one or more calls. Clients of a particular sRPC server can make any of the calls supported by the server. For example, an sRPC server implementing the dictionary service described in Chapter 23 of Comer and Stevens would support the calls initialize(), insert(), delete(), and lookup(), and quit().

An sRPC service call is similar to a normal subroutine or method call, except that an sRPC service call is more limited in the types of parameters it can use. An sRPC service-call parameter can be an integer, a string, or an array. An integer is a signed, 32-bit value. An sRPC string is a sequence of zero or more eight-bit characters (The ISO 8859-1 characters, also known as the Latin-1 characters); an sRPC string is not zero terminated. An sRPC array is a sequence of zero or more values of the array's base type. sRPC arrays are dynamic; they have no fixed maximum size. sRPC Arrays are also recursive; an array's base type may also be an array.

System Structure

The overall structure of a client-server system in sRPC can be shown as

In left to right order, the components of the system are:

Although the diagram shows a single client, an sRPC server can handle multiple clients.

sRPC Components

sRPC consists of two main components: the sRPC run-time system and the srpc-gen interface-code generator.

The sRPC run-time system is responsible for implementing all sRPC functions, including data marshaling, data transmission, and sRPC system-call semantics. There is a separate run-time system for the client and server sides, but the run-time systems can (and should) share much infrastructure code.

The sRPC run-time system is generic with respect to the services it supports; the same run-time system works with all possible services defined in sRPC. The srpc-gen interface-code generator is responsible for creating the code that bridges the gap between the specific requirements of a particular service and the generic facilities of the sRPC run-time system.

Service-Description Files

A service-description file describes the service calls available from a particular sRPC server. The srpc-gen interface generator accepts as input a service-description file and produces as output several interface files that let implementors access and provide services via sRPC.

A service-description file is a text file with a simple format: a service name spec followed by one or more service-call specs. A service-name spec is a single line starting with the text service followed by an identifier giving the name of the service:

service ident

For example, the service-description file for the Dictionary service might start with

service Dictionary

Following the service-name spec is one or more service-call specs. A service-call spec consists of a call-name spec followed by zero or more call-parameter specs. A call-name spec is a single line starting with the text call followed by an identifier giving the name of the call:

call ident

Each call identifier must be unique among all call identifiers in the same specification file.

Each call-parameter spec is a single line of text consisting of a direction, a type spec, and an identifier:

dir type-spec ident

The direction dir is either in or out and indicates if the parameter is an input (in) or output (out) parameter. type-spec indicates the parameter's type; type-spec can be one of int for an integer, string for a string, or array of type-spec for an array containing values of the given type. ident is the parameter's name; the identifier must be unique among all parameter names in the same service-call spec; parameter names may be repeated in different service-call specs.

For example, this service-call spec

call insert
in  string word
out int    inserted
out string emsg

describes the Dictionary service's insert call.

Generic Service Calls

Every sRPC service includes a set of generic sRPC service calls; a generic sRPC service call is an sRPC service call that is always included in any service. The generic sRPC service calls provide management and information facilities to the clients and servers using sRPC. Such facilities include setting up and tearing down connections between clients and servers and receiving information about the service calls offered by a particular service. On the client side, there are generic service calls that allow the client to

  1. setup a local endpoint for an sRPC service and establish a connection to a remote sRPC server for the service.

    call setup
    in string  hostname
    in int     port_number
    out string emsg
    

    port_number is in host-byte order. The sRPC server is located at hostname:port_number. This must be the first service call made by a client. If emsg is empty after a call to setup(), no error occurred during the call; otherwise, emsg contains an error description.

  2. determine the service calls offered by the sRPC server.

    call query
    out string spec
    out string emsg
    

    After the call to query(), spec contains the server's service-description file and emsg contains an error indicator as described above.

  3. shutdown the connection to the remote sRPC server and reclaim the resources allocated to the local endpoint.

    call shutdown
    out string emsg
    

    emsg contains an error indicator as described above. Once shutdown() is called for a particular endpoint, any other sRPC calls to that endpoint are invalid.

    A call to shutdown() effects only the associated endpoint; any other endpoints to the same sRPC server, and any other endpoints to other sRPC servers, remain unchanged.

    The server-side generic service calls allow a server to

    1. initialize the server at the start of service.

      call initialize
      out string emsg
      

      emsg contains an error indicator as described above. initialize() is called once by the sRPC run-time code at the start of execution to initialize the implementor-supplied server code.

    2. shut-down the server code in preparation for stopping the server.

      call shutdown
      out string emsg
      

      emsg contains an error indicator as described above. shutdown() is called once by the sRPC run-time coded at the end of server execution.

    Notice that the server interface does not include the query() generic sRPC service call.

Language Bindings

sRPC is language independent; before sRPC can be used, the features and details described above have to be represented in some programming language. The programming language in which the sRPC features and details are represented is known as the host language, and the process of representing sRPC features and details in the host language is known as binding sRPC to the host language.

The specifics of binding sRPC depend on the host language. There are sRPC language bindings for C++ and Java; the bindings for other host languages will be similar to these two bindings. Keep in mind that these are example bindings; if you don't like these, you're free to make your own.

The Project

This project consists of two parts:

  1. Write srpc-gen.

  2. Write the sRPC run-time system, including the sRPC protocol.

Example

This example demonstrates how sRPC might be used to implement the Dictionary server given in Chapter 23 of Comer and Stevens. The implementor would first first create a service-description file for the Dictionary server:

service Dictionary

Then would follow a sequence of service calls describing the interface to the Dictionary server:

call insert
in  string word
out int    inserted
out string emsg

call delete
in  string word
out string emsg

call lookup
in  string word
out int    found
out string emsg

call quit
out string emsg

Assuming this service-description file is named dictionary.srpc and that srpc-gen produces C++ code, running dictionary.srpc through srpc-gen produces the four files dictionary-client.h, dictionary-client.cc, dictionary-server.h, and dictionary-server.cc.

Suggestions for Proceeding

  1. Choose a host language. This is the language in which users of your sRPC implementation will write client and server code, and the language used in the files generated by your implementation of srpc-gen. However, your implementation of srpc-gen need not be written in the host language. For example, you may chose C++ as the host language, but write srpc-gen in perl.

    Your implementation of the sRPC run-time system will most likely be written in the host language, but that isn't an absolute requirement, although it's the easiest approach to take. For example, If you choose Java as your host language, you can write the sRPC run-time system in either Java, C++, or C; if you use C++ or C you'd hook up to it through the Java Native Interface.


This page last modified on 29 March 2004.