Often it is useful to create dedicated external programs which are optimized to specific tasks or access functionality that simply isn’t provided by Rapture. For instance, perhaps a web based application needs to interface with a running Rapture server and ask for authentication so users can use an on-line form based editor, or perhaps you’d like to provide up to date help file access via the web, or you could even use Rapture to interface with a hardware device of some sort. The point is, that through external processes, the functionality is pretty close to limitless. However, to facilitate the communication between these external processes and the Rapture server, a common interface has to be defined. This is the RMQ (Rapture Message Queue) IPC (Inter-Process Communication) part of Rapture. This allows arbitrary messages to be both sent to a running server, and have a response sent back. This is all accomplished by telling Rapture (at runtime) what function you’d like to handle message requests by setting the game.mqhandler$ resource. That function takes a single string parameter which is set to the value of the incoming message. The function then returns the value of any reply (as a string). That’s it, the rest is handled by Rapture. The contents of the string for both incoming and outgoing is arbitrary, the only limitation is that it be less than 4k (4096 bytes) in length (any excess will be quietly truncated).
There is a command line program (rmqtool) provided with Rapture which lets any external process send (and wait for) messages. Either by writing the message to stdin or by specifying it on the command line, the tool sends the message to a running Rapture server and will optionally wait for a reply (or timeout if no reply is detected). It prints any reply to stdout. This allows easy Unix piping of input/output to interface with rapture.
Let’s look at an example. Let’s say we want to create a CGI web program that will both request the current in-game date as well as a listing of all the players currently on-line. First, let’s declare the function that will be used as the message handler:
function myhandler(msg$)
{
local i;
if( msg$ = "who" )then
return who_list$();
else if( msg$ = "date" )then
return fancy_game_date$();
return "";
}
As you can see, it’s pretty simple in this case. It accepts two types of messages, the “who” message and the “date” message. It simply calls a function and returns the results of that call. If it’s not one of those messages, it simply returns the empty string. Next, let’s actually make sure Rapture knows what function we want to handle RMQ messages:
game.mqhandler$ = "myhandler";
The next step is to actually request the information from the running server (this is Perl code):
$who = `rmqtool -m "who"`;
print "$who\n";
Which might print out the following (depending on who is on-line).
Aeyr, Sarapis, Bob, Jim, Alice
That could then be included in a web page generated from a CGI script or whatever. The same thing could be done with the “date” message.
While this does allow extreme flexibility, it must be noted that this is not designed to be a web server component. If you have lots of web traffic or something that continually sends and receives messages, this system will likely become less appealing. Caching the values you request (such as only requesting the “who” list once a minute) can greatly increase performance. This IPC mechanism is relatively fast, however, the game executable should probably spend more time processing game logic and player input than handling external requests.