web2mush: Serving Interactive Resources to the Web

Glenn Crocker, Novell, Inc.

Abstract

Adding persistent state to Web resources is one of the largest challenges to server authors today. Since the World-Wide Web (WWW) is designed to be stateless, this is a fundamental change to how Web resources are used by Web clients and servers. TinyMUSH, an on-line multi-user game system, is a connection oriented state-heavy resource designed to be used with telnet or similar terminal-oriented programs. Web2mush is a system of programs working together which make access to TinyMUSH systems available to users of the Web through the richer Web interface. The important difference between a TinyMUSH connection and a WWW connection from the server author's viewpoint is their duration. TinyMUSH connections can last for several hours while typical WWW connections often last less than one second. Web2mush also allows multiple simultaneous users through a novel use of Universal Resource Locators (URLs). Web2mush has made an interactive, connection-oriented resource available via the Web. The work on web2mush also points out potential areas for future development in improved client and server support for such interactive resources.

Web2mush Goals

Background

Understanding TinyMUSH

To understand web2mush, we first need to understand a "standard" TinyMUSH connection. TinyMUSH is a server process which accepts socket requests on a single port, maintains multiple simultaneous connections to clients via those sockets, accepts commands from the users thus connected, and presents output via the sockets to the users.

Users can connect to a TinyMUSH with telnet or with special terminal-oriented client programs. The client programs typically provide line editing and command history recall, and some provide output logging and other advanced features.

Typical TinyMUSH configuration

All entities in TinyMUSH are objects which have attributes such as description, location, and owner. Once connected, TinyMUSH users are able to control a player object that can move between room objects, communicate with other player objects, and program thing objects. A good way to think of this is that users are connected to a multi-user user-extensible text-based adventure game.

Understanding the Web

Next, we need to understand a "standard" World-Wide Web connection. WWW consists of an http (HyperText Transfer Protocol) server which accepts socket connections on a single port, reads a URL query from the connected client, outputs the data associated with the URL specified by the user, and closes the socket. Each Web request is a separate connect-get data-disconnect sequence.

Standard World-Wide Web configuration

The important difference between a TinyMUSH connection and a WWW connection is the length of time of the connections--in the case of TinyMUSH, it can be up to several hours; in the case of WWW, the connection often lasts less than one second.

Accessing TinyMUSH from the Web

The first goal of web2mush is to allow Web users to access TinyMUSHes. Unfortunately, the goal as stated is ambiguous. There are several aspects of TinyMUSH that we may wish to serve via the Web:

  1. Object descriptions
  2. Topology information
  3. Interaction with other users
Other systems have provided access to the descriptions of objects contained in a system like a TinyMUSH. This can be accomplished with a configuration like this:

  1. The TinyMUSH server is unmodified, and accepts connections on a socket as usual.
  2. The WWW http server accepts URLs from users and runs a CGI script.
  3. The CGI script connects to a pre-arranged user on the TinyMUSH specified as part of the user's URL.
  4. The CGI script returns the TinyMUSH object description to the WWW user.
  5. The CGI script disconnects from the TinyMUSH server.

Simple TinyMUSH Solution

This simple solution provides access to object and topology information, but does not allow interaction with other users. The main advantage of this approach is its simplicity--the CGI script doesn't have to maintain the TinyMUSH connection. This approach is very "Web-like" (in that it is connectionless or stateless), but is not very "TinyMUSH-like" (in that it is not possible to interact with other users in real-time).

A Complex Solution

Another approach lies at the other end of the connected-ness spectrum.

  1. The TinyMUSH server is unmodified.
  2. The WWW client and http server are modified to maintain their connection, even after the URL's data has been passed from the server to the client.
  3. The http server (or a CGI script) monitors the TinyMUSH connection and provides updates to the URL to the WWW client.
  4. The WWW client renders these modifications as they come.

Complex TinyMUSH Solution

The main feature of this approach is its complexity. To support the long-lived connections, the server, client, and probably HTML itself have to be modified. The result is no longer a normal WWW service, but it is very similar to accessing a TinyMUSH via telnet. This complex solution allows us to serve all of the TinyMUSH system to the Web, but at a daunting development cost. This solution is attractive, and it seems likely that some future version of HTML will provide for this sort of service.

The Middle Ground

Somewhere in the middle lies a gross abuse of the Reload operation:

  1. The TinyMUSH server, WWW client, and http server are unmodified.
  2. An intermediary server is written which maintains multiple connections to a TinyMUSH and allows "connectionless" queries.
  3. This server buffers up output from the TinyMUSH and provides full HTML documents (including changes) upon request via a URL from the client.

The web2mush approach

This approach allows us to serve all of TinyMUSH via the Web without having to redesign the Web.

Middle Ground Detail

Web2mush consists of these parts:

TinyMUSH

TinyMUSH is a daemon which accepts connections on a well-known port, allows users to log in, and accepts commands from logged-in users. These socket connections are kept alive throughout the user's login session, typically for several hours. The commands available to users include look, examine, move, say, and create. By using the move command, the user can cause a player object contained in the TinyMUSH to move from its current room object, through an exit object, to another room object. When a player uses the say command, other players see what is said. It is this sort of unsolicited input that makes TinyMUSH an interactive connection-oriented resource.

mushclient

mushclient is a CGI script driven by a "GET" HTML form which yields URLs such as: http://bob/mushclient/type=login?name=guest&passwd=guest

and: http://bob/mushclient/type=command/auth=184326934?entry=look

mushclient receives these URLs from the HTTP server already split into two parts: $PATH_INFO and $QUERY_STRING. For the first example URL, $PATH_INFO is type=login?name=guest&passwd=guest and $QUERY_STRING is empty. For the second example URL, $PATH_INFO is type=command and $QUERY_STRING is auth=184326934?entry=look.

mushclient connects to server on a pre-configured port, sends $PATH_INFO and $QUERY_STRING (on separate lines), reads from the configured port, writes to STDOUT, and exits when server closes the socket. mushclient is about 60 lines of Perl.

Server

server is a daemon which accepts socket connections from mushclient invocations on a pre-configured port, reads $PATH_INFO and $QUERY_STRING, performs one of several operations, and outputs the result of those operations to mushclient via the socket. The choice of operation type is based on the value of the type= field of the $PATH_INFO variable (which is the first line read from mushclient). Server is approximately 500 lines of Perl.

Server Requests

Login

For login requests, $PATH_INFO contains /type=login and $QUERY_STRING contains something of the form name=guest&passwd=guestpw, which is parsed to mean: "This request is a login request. The user's name is guest. The user's password is guestpw." Upon receiving a 'login' request, server opens a new connection to the TinyMUSH with which it has been configured to interact, logs in with the specified username and password, returns the TinyMUSH login message (converted by server to HTML) to mushclient, and closes the connection to mushclient. The connection between server and the TinyMUSH server is kept open. Server appends a text-entry field to the end of each page it returns. Users use this text-entry field to provide new commands for server to send to the TinyMUSH.

Command

For command-type requests, $PATH_INFO is /type=command/auth=7884738393 and $QUERY_STRING is entry=look. The /type=command part of the $PATH_INFO is how we determine that this is a command, rather than a login request. The /auth=7884738393 part is used for authentication and sequencing. The entry=look is the result of the user typing the word 'look' in the text entry field at the bottom of the previous page of HTML output from server.

Server recognizes that different commands require different HTML conversions, and decides which conversion to use based on the command ('look' in the above example) and based on the output of the command.

Move

When server processes move-type requests, it converts TinyMUSH ASCII room descriptions into HTML and converts exit names into 'move' server request URLs of this form (the original exit name was 'TRAIL'):

http://bob/mushclient/auth=3857304967/type=move?TRAIL

$PATH_INFO is /auth=3857304967/type=move and $QUERY_STRING is TRAIL.

Reload

Reload requests are generated when the user selects their Web client's 'Reload' command or function. During a reload, the server process checks the URLs' user's connection to the TinyMUSH for new output, converts it to HTML, appends it to the pre-existing data associated with the URL, and returns it. This is the mechanism by which a TinyMUSH user logged in via the Web can see asynchronous data, such as another user saying, "Hello."

Authentication and Sequencing

Since the web2mush server process handles multiple simultaneous TinyMUSH connections without maintaining a permanent connection between the users and server, it must be able to separate the incoming requests of multiple users and determine to which TinyMUSH connection the command derived from a given URL should be sent. It does this by embedding unique random numbers in the URLs given to the user as a form of user identification. When the user selects one of these URLs, the server process does a lookup into an internal structure, decides which user the URL came from, and sends the command through the appropriate TinyMUSH connection. The authentication "tickets" are not reused, so the URLs given to users are only valid for one use (plus reloads).

This same sequencing mechanism provides some measure of security as malicious users probing the server with random URLs are extremely unlikely to find a valid authentication ticket. Since TinyMUSH (and unencrypted TCP/IP traffic in general) are inherently insecure, this level of security is deemed adequate.

This technique of sequencing is a good general way to provide a "login"-style connection to Web users, but there are some drawbacks: Because the URLs are only valid for one use, and URLs from previous pages are no longer valid, the user cannot use their Web browser's 'Back' facility to return to previous pages and then select an URL. This is because the server process only considers the authentication tickets in the current page to be valid.

Retaining the old authentication tickets and allowing users to select them would have been technically feasible, but TinyMUSH is so state-heavy that it would have been inappropriate.

TinyMUSH on the Web

Since the descriptions of rooms are passed through server unmodified, room descriptions which include anchors, inline graphics, etc. are made available to web2mush users. This allows users to create custom Web pages in their room descriptions. These pages are seen by web2mush users who enter the rooms, and can include any legal anchor, including inline images, links to sounds, links to other Web resources outside the TinyMUSH, etc.

There is even the potential for web2mush users to create Web resources inside TinyMUSH which are served to non-web2mush Web users. The interesting aspect of this is that TinyMUSH has a built-in extension language, which can now be used instead of languages like C and Perl to author Web software. This facility allows users without Unix accounts and degrees in computer engineering to contribute potentially sophisticated software to the Web. A demonstration puzzle game was written in the TinyMUSH extension language as part of the development of web2mush.

Futures

There are some problems associated with web2mush's unorthodox use of the 'Reload' operation of Web clients. First, client caching must be disabled for web2mush to function properly. This is because a 'Reload' often returns a document with new data appended. The second problem is that forcing users to select 'Reload' frequently is a decidedly annoying user interface decision.

To address the second problem, a Perl script was written which causes X Mosaic to perform a 'Reload' operation periodically by taking advantage of X Mosaic's signal automation feature. A more sophisticated design would use a proxy http server which performs 'Reload's periodically and forces X Mosaic to do a 'Reload' when the data returned by web2mush changes.

It seems likely that HTML and HTTP will be extended to allow servers to interact with their clients in more sophisticated ways without requiring server authors to perform such contortions. Hopefully, web2mush and other interactive Web resources will motivate change to the protocols involved that will remove the current hurdles to development of new Web resources.

Biography

Glenn Crocker is a Software Engineer at Novell, working in Cupertino, CA. He was one of the authors of TinyMUSH 2.0, continues to participate in TinyMUSH development, and administers TinyCWRU (a TinyMUSH server). In his spare time, Glenn collects strange-named beings: a wife (T'Pring), a dog (Senté), and two cats (Arwen and Éowyn).

gcrocker@novell.com