Chapter 10

Implementing Web Chat


CONTENTS

Everybody's talking about it: the ability to utilize the Web to communicate with one another-in real time. Initially, this was limited to IRC (Internet Relay Chat), a protocol such as FTP, or Telnet where you'd assume an alter ego by defining an alias or fake name, and then enter a channel, which is the electronic equivalent of a room where several people would talk, much analogous to the CB radio days.

Let's Talk

The Web has brought a new dimension to online chat-the concept of a "chat room," which takes the straight-text environment of IRC and gives it a visual, virtual world in which to communicate.

There are several methods of implementing Web chat:

Using a custom browser plug-in to handle the chat interface (such as IChat).
Using Java to create a "chat applet."
Using forms and CGI to process the ongoing conversation.

Whichever method you prefer, they all rely on the capability of the user's browser to transmit information back to the server. It is then added to the conversation at large and sent back to the user.

Remember, on the Web, browsers themselves are not interconnected. Each surfer is communicating between oneself and the server. Even if several people are browsing pages from the same server, they are not aware of each other's existence.

Script-Based Chat

One easy method to implement scripted chat is to utilize frames to create "inbound" and "outbound" sections of the browser. In other words, you create a chat environment that consists of two frames:

  1. Top frame-this displays the ongoing conversation.
  2. Bottom frame-this contains a form that the user utilizes to enter the dialog.

One nice example of this is CyberIsland by LinkScape (http://www.pageturners.com/linkscape/), where the basic chat principles are "gussied up" with some good graphics as well (see fig. 10.1).

Figure 10.1 : Generally, Web chat systems are not heavily graphic because they are constantly loading data from the server. However, some judicious backgrounds and lines can make for a pleasing layout.

Listing 10.1 demonstrates the basic <FRAMESET> that sets up everything. As you can see, it's a standard frame construction, with the source documents for each frame being the CGI scripts that drive each section.


Listing 10.1  Framed Chat
<HTML>
<HEAD>
<TITLE>Web Chat</TITLE>
</HEAD>

<FRAMESET ROWS="*,200">
   <FRAME NAME="messages" SRC="/cgi-bin/readchat.cgi">
   <FRAME NAME="submit" SRC="/cgi-bin/writechat.cgi">
</FRAMESET>
</HTML>

Before you actually start setting up the frames and firing chat documents back and forth, you need to get some information from the user. This is handled by the "front door" to your chat system.

The Front Door

Prior to letting someone into your chat room, you need to know something about them, to identify from whom a comment is coming, if nothing else. Most chat systems deal with this through a front door form like the one in listing 10.2. This form gets all the necessary information and then fires up the chat script.


Listing 10.2  The Front Door
<HTML>
<HEAD>
<TITLE>Chat Page</TITLE>
</HEAD>
<BODY>
<H1>Welcome To The Chat Page</H1>
<FORM METHOD=POST ACTION=chat.cgi>
<HR>
<STRONG>Enter Information Below:</STRONG><p>

<TABLE BORDER=1>
<TR>
<TD ALIGHT=RIGHT>User Name:</TD>
<TD><INPUT NAME=chat_username></TD>
</TR>
<TR>
<TD ALIGHT=RIGHT>Your Email Address(*):</TD>
<TD><INPUT NAME=chat_email></TD>
</TR>
<TR>
<TD ALIGHT=RIGHT>Your Home Page (*):</TD>
<TD><INPUT NAME=chat_http></TD>
</TR>
</TABLE>
<P>
<INPUT TYPE=SUBMIT NAME=enter_chat
VALUE="Enter The Chat Room">

<HR> 
</FORM>
</BODY>
</HTML>

Entering Dialog

The user enters dialog through a form and presses the Submit button. The data is then passed off to a Perl script that processes the information and constructs a new HTML page that displays in the user's top frame:

<HTML>
<FORM METHOD=POST ACTION="/cgi-bin/writechat.cgi" TARGET="messages">
<INPUT TYPE=TEXT NAME="dialog" SIZE=40>
</FORM>
</HTML>

The CGI script that is fired when this form is submitted (see listing 10.3) is relatively simple, and uses the same principles as other scripting tricks such as a graffiti wall. In a nutshell:

  1. Parse the input data.
  2. Grab the current dialog database.
  3. Write out the user's comment to the dialog database.
  4. Grab the current dialog page (HTML).
  5. Write a new dialog page.

Listing 10.3  Writing Out New Chat
if ($submit_message ne "") {
    if ($chat_to_user eq "" ||
        $chat_to_user =~ /^all$/i ||
        $chat_to_user =~ /everyone/i) {
        $chat_to_user  = "ALL";
    }
  
    $high_number = &GetHighMessageNumber;
    $high_number++; 
    $high_number = sprintf("%6d",$high_number);
    $high_number =~ tr/ /0/;           
    open(MSGFILE, ">$chat_room_dir/$high_number.msg");
    print MSGFILE "$user_name\n";
    print MSGFILE "$user_email\n";
    print MSGFILE "$user_http\n";
    print MSGFILE "$chat_to_user\n";
    print MSGFILE "$current_date_time\n";
    print MSGFILE "$chat_message\n";
    close(MSGFILE);

    &PruneOldMessages($chat_room_dir);

    $old_last_read = $user_last_read;
    ($user_name, $user_email, $user_http,
     $refresh_rate, $how_many_old, 
     $user_last_read, $high_message) = 
      &GetSessionInfo($session, $fsubmit, $frames);
    $user_last_read = $old_last_read;
}

...

The only major decision is whether to place the new dialog at the top or bottom of the file. IRC users are familiar with how new dialog always appears at the bottom of the chat window, with the conversation getting "older" as the window scrolls up. Web pages, however, are always loaded with new dialog from the top with conversations getting older as you scroll down the screen naturally.

The Chat Window

The top frame simply requests the chat page for display. To force the page to reload every 30 seconds, without having the user's entire screen reformat every time, the client-pull technique is used:

<META HTTP-EQUIV="Refresh" CONTENT="30" URL="/cgi-bin/readchat.cgi">

By having it reload from the script, you force the script to generate the latest amount of chat dialog with each pull. The script that prepares the page (listing 10.4) is straight-forward: Open the file and write it out.


Listing 10.4  Updating the Chat Window
print "Content-type:  text/html\n";
print "Pragma: no-cache\n\n";

print "<HTML><HEAD>";
print qq!<META HTTP-EQUIV="Refresh" ! .
      qq!CONTENT="$refresh_rate; ! .
      qq!URL=/cgi-bin/readchat.cgi>!;
print "</HEAD><BODY>";

open (CHAT, "$chatFile");

while(<CHAT>) {
   print @_,"<BR>";
close(CHAT);

print "</BODY></HTML>";

NOTE
When performing a Web activity that constantly pulls pages, remember browsers cache pages to speed up access to places frequently surfed. With a chat script, you are "reloading" the page in the top frame at a regular interval; however, the URL of the document is not changing. If you let the browser cache the page locally, the local copy will be the one pulled with each refresh.
An easy way around this is to modify the standard content header that your script prints at the top of the page to force the browser not to cache the page:
Content-type: text/html\n
Pragma: no-cache\n\n
When the browser encounters the "no-cache" directive, it won't cache a local copy of the page in memory or on disk.

Enhancements and Extensions

So far, the Web chat system has been fairly simple. In addition, there are several obvious ways to extend the system, including:

As with all the other scripts and tricks discussed in this book, the implementations of these extensions can all be found on the companion CD-ROM in the Source Code section under chapter 9, "Bulletin Boards."

A "Who" Option

Some people are nosy, and want to know more about who they're talking to. For those who "need to know," you can provide an additional option that lists all the information you collect from your visitors as they enter chat.

TIP
If you want to implement this option, you might want to consider offering your visitors the opportunity to decline to divulge information as well, to satisfy the extremely paranoid or the highly secretive.

Multiple Chat Rooms

With only one "chat room" you are either limited to one topic or doomed to mass confusion, as everyone talks about something different. The basic chat structure is adaptable to handle multiple chat rooms by:

Private Chat

Even in public places, such as the Web, people sometimes desire the "privacy" of a "secure" chat. If you think about this, it's not too difficult to set up if you follow these steps:

  1. Add another option to the lower-frame chat form to "lock" the current chat room. This prevents additional people from entering.
  2. Write the lock information out as a flag on the chat files.
  3. When constructing the chat front door, look for the presence of this flag on a chat room. If it is present, do not consider that particular chat room an option.

Remember to "clean up the room" after everyone leaves; that is, delete the conversation files, remove the privacy flag, and make the room available for open chat again. For a complete, running, and private chat example, be sure to check out the companion CD-ROM.

Summary of Web Chat

While implementing a real-time chat room entirely with scripting is probably not too practical, the reload times can become a problem, especially when chatters have the tendency to be rather verbose. It's an interesting experiment in using scripting to get several people to communicate through the Web.

Possible extensions to this technique are:

A periodically updated calendar or alarm clock in which company meetings can be flagged to remind the user.
A customized advertising system where different information, tailored to the user's tastes, is loaded periodically-based on the information the user fills out in the form.

From Here…

For more information on this and other related techniques, check out: