Shockwave Chat
March 12, 1998
by Andrew White
Introduction
The major feature of the recent FileMaker Pro 4.0 database application from Claris (now FileMaker, Inc. ) was the integration of web hosting features into the database application itself rather than using a third party web server and and plugin. While this may seem irrelevant to Director developers, for those lucky enough to have their PC and Macs permanently connected to the Internet via leased lines it does open up some interesting possibilities.
In this article I'll talk about what those possibilities are and how to take advantage of them in your Shockwave movies. I'll be using an online chat system as an example to show how the whole thing hangs together.
FileMaker Pro as a CGI
The vast majority of the CGIs used on the Web are there to provide some way retrieve information from the client and then process it some way, after which the results are returned to the client. The search engine is a classic example of this use, and usually the PERL language comes into the equation at some point - either the whole CGI is implemented in PERL or it is used as a interface to a backend database server running SQL or something similar.
Instead of learning a new (albeit useful :-) ) programming language, why not build solutions based upon the groundwork of other. By using FileMaker Pro as the CGI application you are gifted all of the searching, indexing & data storage you could ever possibly need - all contained within a single file, thereby bypassing any overhead associated with accessing multiple files incurred by the underlying operating system. The only cloud on the horizon is how to host the database files on the Internet.
The current situation exists because the majority of servers on the Internet use a variant of UNIX and can't run standard desktop application software without some kind of emulation package. This situation is changing very rapidly though as more and more companies are linked to the Internet and even if you aren't linked yourself then there are third party hosting services specifically for FileMaker Pro which run on NT and MacOS servers.
If you have no experience of using FileMaker Pro or any similar type of database software then you might want to read this simple introduction.
Shockwave Chat Example
Creating the databases
The first stage in the process is to define and create our databases for holding our data. We will keep things simple in this example but there is no reason why it can't have additional databases defining rooms etc.
Users Database
Firstly we create the users database which is used to hold the current settings for each person in the chat system. We define six fields, although only four of them are absolutely necessary.
Field Name |
Field Description |
---|---|
User |
This is the key field identifies a person in the chat system. Data validation is switched on ensuring that the field is unique, i.e. no two records have the same User field. |
Real Name |
This field holds the person's real name. This field is not essential but could be useful in tracking someone down who abuses the system. |
|
Similar to the field above, the email field is not essential and is just there so that if people have any problems the administrator can contact them. |
Room |
This field holds the current room in which the person is chatting. When the person logs on a script is run which sets this to the value contained within the Entrance global field. In this example the range of rooms is stored in a static value list but there is no reason why a dynamic database driven room system could not be implemented instead. |
Online |
This field tracks whether the users is currently online. This field is set by the logon and logout scripts. |
Entrance |
This is a global field that defines the first room in the chat system for |
After defining all of the fields this is what the users database looks like.
Chat Database
The chat database holds the actual messages that people send. It uses five fields and one relationship. The match field for the relationship is the User field and this is used to auto enter the room field.
Field Name |
Field Description |
---|---|
User |
This field identifies the user that created the message. |
Room |
This field identifies the room that the user was in when the message was created. This field is auto entered based on the relationship from the User match field. |
Date |
The date that the message was created. This is set by auto entering. |
Time |
The time that the message was created. This is set by auto entering. |
Message |
The field holds the actual text of the message. |
After defining all of the fields this is what the chat database looks like.
Constructing Format Files
The way that FileMaker works as a CGI is that any queries submitted by the client and then processed are passed through a parser which formats the returned document based on a format file. Within a format file are custom tags which are replace with data from the database. There are additional tags which also allow you to insert things like the current time & date.
The great thing about these format files is that they don't need to be HTML files - they can be ordinary text files. This means that with careful formatting FileMaker Pro can return a string representation as a list which can be then converted into a list simply by using the lingo function value() - no messy and time consuming parsing of HTML documents. Also the size of the return document is much smaller - no more than a few bytes.
The list of replacement tags is very extensive but this example only make use of a few, which are:
Format File |
Description |
---|---|
[FMP-Record] [/FMP-Record] |
All text within this tag pair is repeated for every returned record. |
[FMP-Field: name] |
This tag is replaced by data from the appropriate field |
[FMP-ValueList: name] |
The text within this tag pair is repeated for every item within the value list defined in the FMPro database. |
[FMP-ValueListItem] |
This tag is replaced by the current FileMaker Pro value list item |
[FMP-CurrentTime] |
This tag is replaced with the current server time |
[FMP-CurrentDate] |
This tag is replaced with the current server date |
[FMP-CurrentError] |
This tag is replaced with the current server error number |
For a full list of tags see the CDML reference database in the Web Tools folder within your FileMaker folder.
If you are using text format files then you need to be very careful when editing them. Ensure that there are no trailing returns, and any text within a [FMP-Record] tag pair needs to be there otherwise the value function will fail and your variable reference will be void.
GET v POST
There are two methods of submitting data to a CGI - GET and POST. GET requires all of the data to be passed in the URL, whereas POST appends the data to the input stream. This means GET is very limited in posting large quantities of data, whereas POST can handle virtually unlimited amounts. Unfortunately netLingo in Director only support the GET method, although the current beta release of XtraNet now has POST support. With the current problems involved in getting xtras downloaded into the browser support folder this means most Shockwave solutions will have to use GET. This means that the amount of data that can be passed is currently limited to 1 KB (including the domain name portion), though some browsers have problems with such long URLs so the TETOTOYTM (Test early, test often and test on your target machine) acronym applies.
Constructing URLs
There are a number of portions to a URL, these being:
URL Segment |
Description |
---|---|
Base URL |
This is the server URL on which FileMaker Pro is running. |
CGI Action |
This is the actual CGI call and is always FMPro? |
Variable Tags |
These tags specify a number of things not least of which are the database to perform the action on. For every URL you'll probably use the many of the following tags.
|
Parameters |
This is the actual field data that you want the action to be performed upon. They generally take the form of a name value pair, e.g. user=AndyW |
Action Tag |
This tag specifies what FMPro action is to be performed and can be one of:
|
These tags would be linked together into one URL using the & character to give you something like:
http:/www.yourserver.com/FMPro?
Db=users.fp3&-Lay=users&-Format=users.txt&-Find
Consult the CDML reference database for further information on what each of the tags does.
Encoding data
One problem with the GET method is that a lot of the characters can confuse the browser so they need to be encoded into a hexadecimal representation, e.g. a space needs to be converted to %20. The following two handlers perform this operation
-- Encode a string into a URL safe form on encode inStr set outStr = "" set numChars = length(inStr) -- These chars are ok in a URL and -- don't need converting set legalChars = "ABCDEFGHIJKLMNOPQRS ¬ TUVWXYZ0123456789" repeat with i = 1 to numChars -- We get and delete the first char -- every time so that Director doesn't -- have to move into the string. set currChar = char 1 of inStr delete char 1 of inStr if legalChars contains currChar then -- Legal char so just append set outStr = outStr & currChar else if currChar = QUOTE then -- Convert " to " & QUOTE & " -- so that when value() -- is performed the list is valid set outStr = outStr & "%22%20%26%20 ¬ QUOTE%20%26%20%22" else if currChar = RETURN then -- Convert RETURN to " & RETURN & " -- so that when value() -- is performed the list is valid set outStr = outStr & "%22%20%26%20 ¬ RETURN%20%26%20%22" else if currChar = numToChar(194) then -- Convert ¬ to " & numToChar(194) -- & " so that when value() -- is performed the list is valid set outStr = outStr & "%22%20%26%20numToChar ¬ %28194%29%20%26%20%22" else -- Just a standard char like ? -- so convert to hex set outStr = outStr & "%" & ¬ decToHex(charToNum(currChar)) end if end repeat return outStr end -- Convert a decimal number into hex on decToHex decNum set hexNum = "" -- Repeatedly divide by 16 until the original -- number is equal to or less than 15 repeat while decNum > 15 set currMod = decNum mod 16 set decNum = decNum / 16 -- If the if currMod < 10 then set hexNum = currMod & hexNum else set hexNum = numToChar(55 + currMod) & hexNum end if end repeat if decNum < 10 then set hexNum = decNum & hexNum else set hexNum = numToChar(55 + decNum) & hexNum end if return hexNum end
Note that special handling of the carriage return, quote and line continuation characters means that the data will look a little strange in FMPro. Take out these lines if you want the data in FMPro to read correctly but be aware that value will fail when the data is returned unless some extra parsing is done before using value()
Rather building a URL build concatenating together huge chunks of text, add each segment to a linear list and then pass it through the following handler which concatenates all of the items in a list into one string.
-- Assemble a list of strings into one string on buildURL inLst set outStr = "" repeat with i in inLst set outStr = outStr & i end repeat return outStr end
This will turn ["http://www.host.com/","FMPro?","-Db=users.fp3","&-FindAll"] into:
"http://www.host.com/FMPro?-Db=users.fp3&-FindAll"
Submitting the URL
Once you have your URL you then need to submit it. All netLingo operations are asynchronous, so you cannot use a repeat loop structure to wait for the data to be returned. This means you have to loop using a exitFrame handler which repeatedly calls netDone to see if the operation is complete.
When you have many net operations happening in rapid succession then using exitFrame can rapidly become very complex - a better way to handle this is to using an autonomous lingo object which sits in the actorList until the operation is complete and then cleans up after itself and calls the appropriate handler to act upon the returned data.
This parent script is such an object - just create the object using new and pass in the URL and handler names along with an object reference if your using an object to handle the returned data. You can even specify an error method if a net error occurs but it's not required and if it isn't specified then the object quietly deletes itself with any error message being displayed.
-- Parent script to handle asynchronous -- getNetText calls property callbackMethod property callbackObj property errorCBObj property errorCBMethod property netID on new me, URL, cbMethod, cbObj, errMethod, errObj -- Store the callback references set callbackMethod = cbMethod set callbackObj = cbObj set errorCBMethod = errMethod set errorCBObj = errObj -- Start the net operation set netID = getNetText(URL) add the actorList, me return me end on stepFrame me -- Check to see if we're done if netDone(netID) then -- We've completed so delete ourselves deleteOne the actorList, me -- Check that the op was performed succesfully if netError(netID) = "OK" then -- If we have a callback object then use call, -- otherwise we use do for global methods if objectP(callbackObj) then call callbackMethod, callbackObj, ¬ netTextResult(netID) else do callbackMethod & " netTextResult(netID)" end if else -- If we have a error callback -- object then use call,otherwise -- if we have and error method use do if objectP(errorCBObj) then call errorCBMethod, errorCBObj, ¬ netError(netID) else if stringP(errorCBMethod) then do errorCBMethod & " netError(netID)" end if end if end if end
Parsing the result
Once the data has been returned then it's simply a matter of using the value function to turn the string into a list before extracting the data using getaProp or getAt. This code snippet is from the chat control parent script:
-- Parse the result of the logon process on logonResponse me, result -- Convert the string into a property list set resultList = value(result) -- Check to see if value return a property list if ilk(resultList) = #propList then -- If the property list contains -- an error property then an -- error occured so handle accordingly if getPropAt(resultList,1) = #error then case getaProp(resultList,#error) of -- The user doesn't exist so -- create a new record 401: newUser me -- Display a generic alert -- for all other errors otherwise alert "An unknown server error occured." ¬ & RETURN & "Please try again later." end case else -- Grab the data from the -- property list and store -- them in the object's properties set recID = "&-RecID=" & ¬ getaProp(resultList, #recID) set lastTime = getaProp(resultList, #time) set lastDate = getaProp(resultList, #date) set room = getaProp(resultList, #room) -- The logon process was successful so -- change the mode property set state = #online -- Get the list of rooms and the users -- in the current room getRooms me getIRUsers me end if else -- The value() function failed so -- just display a generic error alert "An unknown server error occured." ¬ & RETURN & "Please try again later." end if end
If you're planning on editing records then it's a good idea to grab the record id and store it in a property. This id number is unique to a record and never changes, even if other records are deleted. The -RecID variable tag is required for editing records in a URL.
Chat.dir - The Director Movie
I won't go into too much detail about the movie as the downloadable sample has plenty of comments in the scripts, but the basic functionality consists of three tabbed panes which are:
Message Pane
The message pane is the main screen where all of the chatting is done. There are four text fields which hold the incoming messages, the outgoing message, the users in the current room and the rooms available on the system. The are three buttons Logon, Logout and Send - all of which do the obvious. Before the user can send a message they have to logon and if the movie is quit then the stop movie handler sends the logout command to tidy things up.
Status Pane
This pane has one function - it shows the list of people online even if the users is offline. This allows the users to set the update frequency to 5 or 10 mins and then keep an eye out for someone they're trying to chat to.
Options Pane
The options pane is where the base URL of the chat server is set. Also the user's settings are stored here along with the frequency with which updates are fetched.
Chat Parent Script
The chat parent script controls the submitting of URLs and the display of the results. Although it is lengthy it consists of mainly a series of initiator and responder methods along with a stepFrame method which handles the submitting of URLs.
An initiator method builds a URL and then submits it using the asynchronous getNetText object outlined above, along with the name of the appropriate responder method. When the getNetText operation is complete the responder method is called and the data is formatted appropriately.
Other Possibilities
There are a number of possibilities which can be achieved with using FileMaker as a CGI engine, here are just a few of them:
- Extensions to the chat demo
- Private rooms with password protection
- Dynamic rooms where users can create their own rooms
- Direct messaging between two users
- An search engine for archived messages
- Online games
- Multi-User Dungeon type games
- Turn based games
- High scores database for online games
- Intranet CBT applications
- Lesson server
- Performance recording
- Database lingo script management system
- Online commerce
I hope you agree that using a database product such as FileMaker Pro offers some interesting possibilities for enhancing interaction with your Shockwave movies but there's no need to restrict them to just Shockwave - the above techniques will function just as well in web enabled projectors or even within the authoring environment as a MIAW authoring tool. If you're working on a distributed project then using a networked database can really give you an edge.
Further info
There is a downloadable demo of FileMaker Pro which is restricted to 50 records available from the Claris web site
Web Sites
- Claris / FileMaker, Inc - The home page for Claris / FileMaker, Inc
- FileMaker Pro - This is the Claris authored web site all about FileMaker Pro
- ClickWorld - This is a third party web site all about FileMaker Pro
- Blueworld - This is the home page for Lasso, which provide the technology for FMP4
Mailing lists
Mailing List Name |
Description |
---|---|
FMPro |
This is a general FileMaker Pro list - good for all round design issues. |
FMPro-L |
This is another general FileMaker Pro list - good for all round design issues. The traffic on FMPro and FMPro-L is very high (more than 80 messages per day per list). |
FMP-Web |
This list is dedicated to using the web features of FMPro 4 and it's CDML tag library. |
FMPro-cgi |
This list is dedicated to the use of FMPro as a CGI using any of the third party products such as Lasso, Tango and Web FM or the built-in Web Companion. |
Lasso |
This list is dedicated to using BlueWorld's Lasso plugin and CGI which links a standard web server with FileMaker Pro. Since the Web Companion is based on Lasso 2.0, this list is useful to people who are using the built-in features of FMPro 4 as the tags are very similar. |
The source files for this article, including FMP files, are available for download (SIT or ZIP).
Copyright 1997-2024, Director Online. Article content copyright by respective authors.