9 Introduction

A large fraction of client/server applications fall in the same simple pattern: there is a basic service encapsulated as an object and we wish to allow remote clients to send requests to this object, to be processed at the server host.

The basic idea is to make available to clients a procedure that forwards a client's request to the live server object. This forwarding is effected by means of a port. The forwarding procedure itself is made available indirectly through a ticket. This ticket is placed in a file that is accessible through a URL.

9.1 A Generic Server server.oz

It is straightforward to write a generic server module that exports a Start procedure. The latter takes 2 arguments: Proc the object or procedure implementing the service and File the name of the file where the ticket should be saved. Proc is intended to be applied to messages forwarded by clients.

The forwarding procedure Proxy takes the clients message Msg and sends request(Msg OK) to the server's port. The server binds OK to true or false depending on whether the Msg is processed successfully or an exception is raised.

functor 
import Connection Pickle
export Start
define 
   proc {Start Proc File}
      Requests P = {NewPort Requests} Ticket
      proc {Proxy Msg}
         if {Port.send P request(Msg $)} then skip 
         else raise remoteError end end 
      end 
   in 
      {New Connection.gate init(Proxy Ticket) _}
      {Pickle.save Ticket File}
      {ForAll Requests
       proc {$ R}
          case R of request(Msg OK) then 
             try {Proc Msg} OK=true catch _ then 
                try OK=false catch _ then skip end 
             end 
          else skip end 
       end}
   end 
end 

The server functor will be used as an import in subsequent examples and can be compiled as follows:

ozc -c server.oz


Denys Duchier, Leif Kornstaedt and Christian Schulte
Version 1.4.0 (20080702)