The daytime server example from the last section demonstrated the nuts and bolts of using each of the three communication techniques for applet-servlet communication. It didn't take advantage, though, of the persistence gains when using socket communication. Nor did it show off the simplicity of RMI communication or the elegance of RMI callbacks (where the servlet can invokemethods of the applet). It also didn't provide a compelling reason for why one servlet should support all the communication techniques--there was no state to maintain or complicated code base to collect in one location. So, before we end our discussion of applet-servlet communication, let's look at a more sophisticated example: a chat server, implemented as a servlet, that supports clients connectingvia HTTP, non-HTTP sockets, and RMI.
We'll build this chat server using all three communication techniques so that it can take advantage of the best, most efficient solution for each client. For example, when the client supports RMI, the servlet can be treated as a remote object, and (where possible) it can treat the applet as a remote object, too. When the client doesn't support RMI but cansupport direct socket communication, the chat server can utilize socket persistence and communicate with the client using a non-HTTP socket protocol. And, of course, when all else fails, the chat server can fall back to using HTTP. It would rather not fall back because HTTP, being stateless, requires that the client poll for updates. But for many clients, HTTP is the only choice.
The chat serveris implemented as a single class with a single instantiation because it has a large amount of associated state and a fair amount of code that would otherwise have to be repeated. To separate it into three classes, one for each protocol, would demand excessive interserver communication and replicate the core chat server code three times. Implementing the chat server as a servlet provides a simpleway for one object to make itself available via all three communication techniques. By being an HTTP servlet, it has built-in HTTP support. And by extending the RemoteDaemonHttpServlet class, it can also easily gain support for non-HTTP socket and RMI communication.
Note that although you'll see the code in its entirety, we won't be fully explaining each and every line. To do so would extendthis chapter beyond a reasonable length, assuming we aren't there already. Therefore, we'll explain the issues as they concern applet-servlet communication and rely on you to examine the code to understand all the details.
10.3.1. The Design
Figure 10-3 shows the chat applet in action. Notice that it uses a large TextArea component to display the running conversation, with a small TextInputcomponent underneath where the user can post a new single-line message. As each contributor composes a message, it's sent to the chat server and distributed to the other chat clients in various ways.
Figure 10-3. The chat applet in action
HTTP chat clients post their messages to the server using the HTTP POST method. The applet takes the new message from the TextInput component when the userhits Enter, URL-encodes the message, and posts it to the servlet as a message parameter. It's all very straightforward. What is a bit more complicated is how an HTTP chat client manages to get the other clients' messages. It uses the HTTP GET method to receive each message, but it has a problem: it doesn't know when exactly there's a new message to get. This is the problem with a unidirectionalrequest/response communication paradigm. The client has to either periodically poll for updates or simulate bidirectional communication by making a series of blocking GET requests. By that we mean the chat client initiates a GET request that blocks until the server decides it's time to return something. For our example, we implement this simulated bidirectional communication.
Socket chat clients,...