There is little more to the implementation of Web-O-Matic than that.
Starting an application creates instances of its pages, and these create
instances of their component objects. When the server is asked for a
page, it locates the correct application instance, then the correct
page, and calls its emit
method.
One subtlety here is the fact that the HTTP protocol is ``stateless'', i.e. no transaction knows anything about any previous one. This raises the question of how, when the client interacts with an existing application, the server can locate it. This is in fact a notorious problem in Web programming. Some of the first users to encounter it in a big way were supermarkets with Web pages for on-line ordering; because of the need to preserve information about the client's order from one transaction to the next, it often goes under the name of the ``shopping trolley problem''.
The usual solution, which Web-O-Matic follows, is to embed a session
identifier in pages sent back to the client, either in a URL or in
hidden fields inside a form. There are some problems to do with
browser caching and backtracking over old pages which I ignore here.
When the server first creates a new application instance, it gives it a
unique identifier. It also stores a pointer to the
instance, indexed by this
identifier, in a global Object Rexx ``directory'' (an associative array)
called .environment
.
Like other Object Rexx objects, this directory
persists after the command file that created it has exited, so
it will still be in existence for future transactions.
As well as using the identifier in this global index table, the server
also embeds it in all the URLs that can initiate future transactions
specific to this application (e.g. the action URLs of forms), marking
them specially by a tag such as *F
. This means that if one of
these URLs is sent back to the server, it can then extract the
application identifier and look up the corresponding application
instance in .environment
.
Just as .environment
provides a way of looking up application
instances, so each application instance has a table of the pages and
other instances it contains. These tables are used, for example, in
processing the name-value pairs contained in data sent back from a form.
Each pair includes the identifier of the field or other element to which
the data belongs, which can be used
to find the corresponding instance inside the application. The instance
can then be sent its data and update its state as appropriate.
It is worth adding that in October 1996, we started experimenting with Netscape cookies [Netscape Cookies]. These are a general mechanism for allowing the browser to store and send back information about the state of a transaction: they avoid the need for the server to create its own session identifiers, and associated problems connected with caching and backtracking over old pages. Because they are not part of any Web standard, we have avoided using them until now, but we feel that cookie-compatible browsers are now so widely available that most of our users will be able to cope.