Instant Messenger Application
This tutorial shows how to build the web-based Instant Messenger application. The application is a good example of building on top of a welldefined GWT-RPC interface. Every client that loads the application will connect to a servlet on the server and make method calls through RPC. Each client connects to the same server, so it is possible for clients to collaborate with each other. The chapter also looks at building an unobtrusive user interface that integrates well with an existing web page and that only presents information to the user when necessary. We close the chapter by seeing how events can be added to HTTP using GWT-RPC and how to integrate with server features that make event-based protocols more efficient. You can work with a running instance of this application at http://messenger.gwtapps.com.Using the Collaborator Application Pattern
Desktop applications are typically written for people working individually. This makes sense since desktop computers only have one person using them at a time. However, in the real world we tend not to work alone but in teams and multiple people have to collaborate on a single document. For example, many document-based applications are single-user based even when certain documents need to be edited by more than one person. Applications typically don’t have a way to manage this type of collaboration. We resort to passing documents through e-mail or copying them to disk. The Collaborator Application pattern addresses the awkwardness of manual collaboration by building collaboration systems directly into the application.
Building collaborative applications is made substantially easier due to the Internet and its pervasiveness. We can fairly simply transfer data from one source to another. Every person who needs to collaborate just must be able to connect to the Internet and use a web browser. It’s important to have low user requirements for collaboration, even more so than for a single- user application, so everyone who needs to be involved can get involved. Traditional web applications have provided a great collaboration platform in this respect, as shown by the popularity of e-mail and other online collaboration applications. The low barrier to entry for Ajax applications can bring richer experiences to web collaboration.
To build an application using the Collaborator pattern you need to define your model as a centralized model that is accessed through a controller, as illustrated in Figure 1. Each collaborative client interacts with the controller to operate on the model. The controller is then responsible for informing the remaining clients of the model changes. You may be thinking that using a collaboration pattern like this can be a challenge for applications that have their communication based on HTTP, because HTTP does not let servers send data to clients without a request being sent by the client. We’ll look at solutions to this problem later in this chapter.
Figure 1
Instant Messenger Design
If you’re reading this tutorial you most likely are familiar with what an instant messenger does. You’ve probably run into them many times and may even use instant messenger services on a daily basis. Their job is to provide instant textual communication between two or more people that is more conversational than e-mail and less intrusive than a phone call. They have been gaining usage with hundreds of millions of users[ Based on a February 2006 comScore survey (www.comscore.com/press/release.asp?id=800) ]. This is a truly successful
desktop Internet application only rivaled by e-mail clients and web browsers. Bringing this type of application into a browser through Ajax provides the added benefits associated with web-based applications: giving people the ability to communicate from anywhere with a web browser without the need to install client software. Furthermore, the ease of running, building, and deploying an Ajax instant messenger means that it can be used easily in many specialized situations without any barriers to entry.
For this sample application we will create a specialized instant messenger for a web page. It will integrate with a web page as an embedded widget complementing the page’s existing purpose with presence [ Presence is an instant messenger feature that provides realtime online status for you and your contacts ] and instant communication among its users. It will accomplish this by providing a contact list that has, instead of a list of friends or colleagues, a list of visitors to the web page. A visitor will be able to supply his name to be added to the list, and then be able to see other visitors and interact with them through instant messages.
Typically with instant messenger systems the clients do not connect directly to each other; instead, they relay messages through a server. Our application will do the same. Figure - 2 shows a simplified illustration of how clients communicate with each other through the server.
When the client loads the web page, the GWT application will be loaded as well and will connect to the server. The user can input a name and then receive events from the server, such as other users viewing the page and coming online or leaving the page, and messages sent from another user.
Figure - 2
Users can also send messages to other users. The server receives these requests and provides responses in a typical request-response behavior, and it also sends events based on these requests to other users using event protocol behavior.
The Instant Messenger server will run as a GWT servlet with a GWT-RPC interface. The clients will connect and make method calls to the servlet to support the instant messenger functionality. The servlet will implement the RPC interface and provide an event broadcasting system to each client. We’ll discuss the event implementation over GWT-RPC later in this chapter.
The application’s internal design follows the Model-View-Controller architecture. The model represents the objects on which the application operates, including the contacts in the contact list and messages. The view presents the contact list and other windows required to render the Instant Messenger on a web page. The controller implements communication with the server and manages model objects to be rendered in the view.
The Model
The Instant Messenger application’s model has three classes: ContactList, Contact, and Message. These classes are very simple and it is easy to suggest that they are not needed in this application; however, one goal of this sample application is to illustrate how to organize your code. If we were building more functionality into this application, we would be putting more data into our model and would find it useful to separate the application’s components.
Another benefit of the model for this application and for the use of GWT for client applications is that we can share our model objects with serverside code. Since we are implementing the server as a servlet, its implementation is also in Java. Furthermore, GWT-RPC allows transferring of Java objects, which lets us use our model objects again for the structure of our protocol’s data.
So let’s look at the structure of the model. If you’re familiar with instant messenger applications, the UML in Figure - 3 seems intuitive.
The ContactList class contains a list of Contacts and a me attribute. This attribute is a reference to a Contact instance that represents the current user. The Contact class has a name attribute representing the contact’s name, and the Message class has a message attribute for the body of the message. These classes can easily be expanded to add functionality to the application. Also notice that the Message and Contact classes implement GWT’s IsSerializable interface. Implementing this interface and creating a no-arg constructor allows their instances to be transferred over the GWT-RPC protocol. As of GWT 1.4 you can use Java’s Serializable interface instead.
These objects are implemented with simple Java code. The following code shows the implementation for the ContactList class:
public class ContactList {
private Contact me;
private List contacts = new ArrayList();
public ContactList( String name ){
me = new Contact( name );
}
public Contact getMe(){
return me;
}
public void addContact( Contact contact){
contacts.add( contact );
}
public int getContactCount(){
return contacts.size();
}
public Contact getContact( int index ){
return (Contact) contacts.get(index);
}
}
public class Contact implements IsSerializable{
private String name;
public Contact(){}
public Contact( String name ){
this.name = name;
}
public String getName(){
return name;
}
}
This is another simple class. It has just one attribute, the contact’s name. This class can be extended to provide more functionality. For example, you could add an e-mail address so that it could be displayed as a link for the user on the page to e-mail other users. Here we see the benefit of the model with this change. The change would be easily available to the controller, the server (since the model will still transfer over RPC), and the view.
The final class in the model is the Message class:
public class Message implements IsSerializable{
private String message;
public Message(){}
public Message( String message ){
this.message = message;
}
public String toString(){
return message;
}
}
Again, this is another simple class in our model. It has just one attribute, the message body. This class can also be easily extended to provide more information, such as adding a timestamp.
Building a Complementary Interface
This application’s view is responsible for presenting users with instant feedback about the presence of other users on the page and their messages. Typically an instant messenger sits hidden in the taskbar of an operating system, or its contact list fits snugly out of the way at the side of the desktop. By contrast, our Instant Messenger application can’t interact with the desktop or a taskbar and has to share space in a browser window. We’ve chosen to implement the messenger as a complement to an existing web page, so it should fit snugly somewhere on the page that does not interfere with the page’s main usage. We will insert the application on the web page based on an HTML element with the ID messengerView, so it is up to the person who implements the web page to define where this element is displayed. Typically it would be displayed in a page’s sidebar, out of the way of the main content, as illustrated in Figure - 4.
Using this defined area for the application is sufficient for logging in with a display name and presenting a list of other users on the page, but we need another view to display and send messages. Again, it is good to follow the example of a desktop messenger here since people are already familiar with this interface. In a desktop instant messenger, a window pops up when another user sends a message. This can be somewhat intrusive since the user could be working on anything on her computer when the window shows up. Some messengers show a nonintrusive toaster-style pop-up in the bottom, right corner of the screen. This pop-up doesn’t take the focus away from what the user is working on, but provides the ability to click it to bring the Chat window to the foreground. In our Ajax version we don’t have to worry too much about interrupting work on the desktop since we can only notify users of an incoming message in the browser window, but we can use the idea of a pop-up in the bottom, right corner to make the notification more familiar to users. Our Chat window will pop up in the bottom, right corner with all the widgets needed to display messages from the other user and send messages to him or her. Figure - 5 illustrates how the Chat window will be displayed in this application.
The pop-up appears in the bottom, right corner and overlaps whatever content is currently at that location. The user can have more than one conversation. When more than one pop-up appears, we will make it appear to the left of the previous one.
The sequence of events that occurs in the application’s view starts with the sign-in view being displayed in the contact list’s location and asking for the user’s display name. After the user provides a sign-in name, the contact list displays, the application starts receiving events from the server, and
the view responds to these events by rendering the model. The first events that the application may receive are new contacts to be displayed in the contact list. Then the view may receive new messages it will display in a Chat window, one per contact. The view can also receive events from the
user, including opening a Chat window by clicking on a contact. The user can enter messages into a Chat window, which the view sends to the controller to send to the server so that the recipient will receive the message.
To provide this functionality we need four view classes. The MessengerView class manages the views in the application, and the SignInView class provides a view for the user to enter a display name. The ContactListView class shows a list of Contacts on the page and allows the user to open Chat windows with each. The ChatWindowView class provides the list of messages for a chat between two contacts and allows the user to send messages. The UML diagram in Figure - 6 shows these classes.
---------pending----------------
0 comments:
Post a Comment