Java Q&A

How do you write a Java-based chat program? Cliff shows you how, starting with a C++ server and Java client.


June 01, 1996
URL:http://www.drdobbs.com/jvm/java-qa/184409906

Figure 1

JUN96: JAVA Q&A

JAVA Q&A

How Do I Write a Chat Program?

Cliff Berg

Cliff is vice president of technology at Digital Focus. He can be contacted at [email protected]. Submit your questions to the Java Developer FAQ Web site at http://www.digitalfocus.com/faq/.


Chat programs allow people to communicate simultaneously across a network. Everything you type into a chat window is broadcast to the screens of all other users currently logged into the program. Chat programs originated with simple text-only capabilities (like the UNIX talk program) and have evolved into elaborate graphical environments. Unfortunately, everyone who wants to "chat" has had to obtain and install compatible chat programs. Java solves this problem by making it possible for chat programs to be hosted on a Web site and downloaded for execution with the click of a button--no installation, no purchase. Just click and start chatting!

Chat programs are genuinely useful. Many chat programs allow discussions to be saved in a log file, as a record of points made or decisions reached (or jokes told). In short, chat programs are fun, but they can also be used to do real work. We've used a chat program to coordinate the activities of software developers separated by continents, and without adding a cent to our phone bill! (One relative of mine even uses a chat program to communicate with family in Rangoon.)

Real chat programs have features such as private chat "rooms," special identities, and so on. I'll ignore these embellishments to demonstrate the fundamental techniques.

The two basic chat architectures are peer-to-peer and client/server. A peer-to-peer design requires no server program, but is far more complex to implement. A client/server design requires a chat "server" program that serves as a switchboard or data-routing center for all ongoing chat sessions.

In this case, the server program runs on a UNIX Web server, since this is the typical configuration. The Java chat program can then be hosted on a Web page on the server machine, with the chat program server running on the same machine. In essence, to make this work, you need:

When someone goes to the HTML page that has the Java chat client on it, the Java client is automatically fetched and run on the user's machine. The client program will then set up a communication session with the chat server program, which must be running all the time on the Web server. Once the session is established, users can then join any ongoing chat session.

Figure 1 illustrates the basic architecture of the system. All data (keystrokes) entered by any client is sent to the server, which then rebroadcasts the data to all clients. It is conceptually simple, and thanks to Java's streamlined communications-programming classes, is surprisingly straightforward to implement.

There is a hitch: Most Web servers still do not have Java available on them, and Java is needed to run the server component if it, too, is in Java. Therefore, we'll write the server in C++, and the client in Java. You can then put the client on a Web page: The Web server does not need to understand Java to host Web pages with Java on them. The only thing that is required is that the client platform (typically Netscape) be able to run Java.

The Java Client

The chat client has three main classes: ServerChat, UserChat, and Chat, the last of which is an applet class that instantiates the other two. ServerChat, a thread class, is capable of running asynchronously in its own thread. This is good because its main job is to monitor the connection with the chat server program across the network and handle asynchronous incoming data from the server. UserChat, on the other hand, is the component that handles asynchronous data (input characters as they are typed) from the user. UserChat forwards these characters to the server program over the communication line.

The most complex part of the program is the ServerChat class. Yet Java makes even this component easy to write compared to an equivalent program in C. You don't have to worry about things like network byte order or any details usually required for TCP/IP programming.

ServerChat has a constructor and two primary methods: readln(); and run(). ServerChat extends the TextArea class, so it inherits all of the behavior and features of a Java TextArea, which is a scrollable text window. Data retrieved from the server is displayed in this window. ServerChat adds an important feature to TextArea--a thread. The constructor for ServerChat creates a new thread for itself to run in; later on, when the applet initializes itself, it will call the thread's run() method (actually it calls start(), which then calls run()), which starts the thread running.

ServerChat's run() method loops indefinitely, blocking on a read on the communication link. Whenever a character is received, the thread resumes and adds the incoming data to its text area by calling insertText(), automatically scheduling a repaint of the text area. Thus, incoming data is asynchronously displayed on the screen.

Retrieving data from the server link is achieved by the readln() method, which performs a read on the socket's input stream and tests for the case in which there is no data to read. It returns any retrieved data as a Java string value.

The UserChat class also extends from TextArea. Thus, user input is entered into this text area (one window), but data received from the server is displayed in ServerChat's text area (another window). If you prefer a single window, you can refrain from making ServerChat extend TextArea, and modify ServerChat to do its insertText() on the UserChat window instead.

UserChat has one primary method, write(). It converts a Java string to an equivalent stream of ASCII bytes, sending them to the server on the socket's output stream.

The Chat class has a constructor and three primary methods in addition to a main method for running this applet as a stand-alone program from the command line. The three methods are init(), makeConnection(), and handleEvent(). init() establishes a connection with the chat server program on the Web server by calling makeConnection(). If it succeeds, it then starts the ServerChat thread.

Java has built-in support for TCP/IP. This is implemented in the Socket and related classes. To establish a TCP/IP connection with a remote server, you create a Socket object. To send and receive data across that socket, you get the input and output stream handles of the socket. This is what makeConnection() does, along with providing a little user-friendly echoing of its progress along the way, including the remote and local IP addresses (proof that a connection was made).

Finally, handleEvent() traps all GUI-related events that occur within the applet, then checks for a key-press event. When this occurs, the keystroke is inserted into the UserChat text area, and the keystroke is forwarded to the chat server program for rebroadcast to all other listening chat clients.

handleEvent() must have some special code to work around a bug in the Java toolkit. The period character (".") does not generate a KEY_PRESS event when entered in a TextArea, like other characters do, so you have to watch for its KEY_RELEASE event instead. (Using KEY_PRESS is better for other characters, because characters seem to be converted to uppercase by the time KEY_RELEASE is generated.) A practical chat program will also handle backspacing (this one does not) and multiple-character events (the key held down).

An alternative implementation would be to encapsulate the keystroke handling in the UserChat class. However, this has a disadvantage: The UserChat text area would always have to have focus to receive the input (an annoyance to users). If the applet processes the keystroke events instead, then it does not matter which subcomponent has focus, since the events will always bubble up to the applet that owns them.

The Server Program

Because Java has yet to be supported on most Web servers, we will provide a C++ implementation of a chat server program. (We used the gcc GNU C++ compiler.) The program must be running to be accessible; your Webmaster can explain options for having the program run all the time. Alternatively, you can simply log on with Telnet and start it by hand at any time. If you are lucky enough to have a dedicated Internet connection, you can install the server program on your own machine.

It is interesting to compare the C++ program with the Java program. While they do different things, they are not too different in the functions they perform. However, the Java program is easier to read and understand.

The Applet HTML

To use the chat program, all you need to do is go to a Web page that hosts the client on a server running the chat server. Example 1 is the HTML code the Web page should contain. The [Text Chat Applet Would Run Here] is for those forlorn surfers who do not have a Java-capable browser. They will see this message, and dream about all the applets that they are missing. If you can run Java, you will see the chat applet with its two text area windows. For the browser to find the chat client's Java classes, the classes merely need be in the same directory on the server as the HTML page. Otherwise, you will have to include a codebase parameter in the applet tag specifying the directory or URL where the classes are to be found.

The Java client and C++ server source code is available electronically; see "Availability," page 3. Source code for a more advanced chat program,"Whiteboard," is available at (http://www.digitalfocus.com/ ddj/code/). It uses the same principles to implement a graphical whiteboard that many people across the Internet can draw on simultaneously.

Figure 1: Basic architecture of the chat system.

Example 1: HTML code for a web page hosting the chat client.

<html><head><title>Chat Client</title></head><body bgcolor="#ffffff">

<applet code="Chat.class" width=600 height=400>
<h2>[Text Chat Applet Would Run Here]</h2>
</applet>

</body></html>

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.