Exercise 3: Server Interact with Chat Application (20
minutes)
In this exercise, you will learn how to implement a servlet to interact
with the Chat
application by using Grizzly comet framework API.
Background Information
For the Chat application developed in exercise 1, we only need to
implement the application in the client with Dojo or other
Ajax
components. It is very easy to develop as it is server agnostic if the
server supports Bayeux and cometd. However, if
we want to have some control on the server side like receiving some
messages from the server, or interacting with server in
certain way, we will need to use Grizzly comet
framework to implement the interaction
between server and client.
Steps to Follow
We will continue on the chat
application created in exercise 1.
This will all run on our familiar Glassfish server
and many of the steps you will be familiar with from previous exercises.
- If NetBeans is not already running, start it.
-
Let's make a copy of the chat application. Right
click on chat
application and select copy from the list as illustrated in the
following figure.

-
In copy project panel, type chat_externalServlet
as the project name and choose location where you want to put this
project and then select copy to execute copy project.
-
Now create a new servlet in the
project. Right click Source Packages and choose New from the
list
and then select Other as shown below.
- In New File panel , select Web as the Categories and
Servlet as the File Types and then select Next to continue
-
Now configure the New Servlet. Type ChatExternalServlet
as the Class Name, choose <default package> as the
Package, and then select Finish
to create the servlet.
-
Now we need to add the Comet libraries to our
project.
-
Right click the chat_externalServlet
node and select Properties from the list.
-
Find the project's Libraries in the left hand side
of the window and select it.
-
Click Add JAR/Folder button on the right side.
Select the following two JAR's from the <lab_root>/exercises/exercise3.Click
OK to finish Library selection.
- grizzly-comet.jar
- grizzly-cometd.jar
We will develop a simple servlet that will interact with
the chat application via a simple HTTP request.
-
Open ChatExternalServlet.java
under Sources Package in NetBeans.
-
The following is a simple servlet to start with
with. Copy and paste the code below into ChatExternalServlet.java
in NetBeans. Pay particular attention to the code in bold.
import com.sun.grizzly.comet.CometContext;
import com.sun.grizzly.comet.CometEngine;
import com.sun.grizzly.cometd.bayeux.Data;
import com.sun.grizzly.cometd.bayeux.DeliverResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Simple Servlet that update the chat application via a simple Http request
*
* <code>
* http://localhost:port/cometd/ChatExternalServlet?user=me&message=hello
* </code>
*
* @author Doris Chen
*/
public class ChatExternalServlet extends HttpServlet {
/**
* All request to that channel will be considered as cometd enabled.
*/
private String channel ="/chat/demo";
/**
* Initialize the Servlet.
*/
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
if (config.getInitParameter("channel") != null){
channel = config.getInitParameter("channel");
}
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
/**
* See
* @param request
* @param response
* @throws javax.servlet.ServletException
* @throws java.io.IOException
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// message and user are part of the simple HTTP request will invoke late.
String message = request.getParameter("message");
String user = request.getParameter("user");
ServletOutputStream out = response.getOutputStream();
//create the comet context with the specified channel.
CometEngine engine = CometEngine.getEngine();
CometContext context = engine.getCometContext(channel);
if (context != null && message != null) {
Map<String, Object> map = new HashMap<String, Object>();
// text and user are defined entry in the previous chat application.
map.put("text", message);
map.put("user", user);
//Construct a Bayeux response message using Data and DeliverResponse.
Data data = new Data();
data.setMapData(map);
DeliverResponse deliverResponse = new DeliverResponse();
deliverResponse.setChannel(channel);
deliverResponse.setData(data);
deliverResponse.setLast(true);
deliverResponse.setFollow(true);
deliverResponse.setFinished(true);
//send the Bayeux message out by invoking notify().
context.notify(deliverResponse);
out.println("Data is sent.");
} else {
out.println("No data is sent.");
}
}
}
- Understanding the code. In the example
above, we will generate a cometd Bayeux message in a servlet ChatExternalServlet.java.
- First, we import all the Grizzly Comet Framework
packages at the beginning:
import com.sun.grizzly.comet.CometContext;
import com.sun.grizzly.comet.CometEngine;
import com.sun.grizzly.cometd.bayeux.Data;
import com.sun.grizzly.cometd.bayeux.DeliverResponse;
- In doPost() implementation, one can get a
CometContext as follows:
CometEngine engine = CometEngine.getEngine();
CometContext context = engine.getCometContext(channel);
In our case, the channel is
"/chat/demo" which is defined in
exercise
1 chat application.
- In doPost(), we construct a Bayeux response message
by using classes in package
com.sun.grizzly.cometd.bayeux. The classes that we need to use are
DeliverResponse and Data. It is constructed as follows:
Map<String, Object> map
= new HashMap<String, Object>();
map.put("text", message);
map.put("user", user);
Data data = new Data();
data.setMapData(map);
DeliverResponse deliverResponse = new
DeliverResponse();
deliverResponse.setChannel(channel);
deliverResponse.setData(data);
deliverResponse.setLast(true);
deliverResponse.setFollow(true);
deliverResponse.setFinished(true);
Note that
- text and user headers are defined in exercise 1 chat
application.
- deliverResponse.setLast(true) indicates that this is
the last Bayeux message in this Http response.
- deliverResponse.setFollow(true) indicates that this
is not the first
Bayeux message in this Http response.
- deliverResponse.setFinished(true)
indicates that the underlying connection needs to be resumed.
Then we can send the
Bayeux message as follows:
context.notify(deliverResponse);
With the NetBeans IDE
-
Open sun-web.xml in NetBeans. The sun-web.xml is located in chat_ExternalServlet project under /Web Pages/WEB-INF.
In Context Root area, type /cometd
so it will enable comet servlet once the project is invoked.

-
Make sure the comet is already enabled in GlassFish
and GlassFish is already started.
See exercise 0 for detail on how to enable comet support in Glassfish if you haven't done son.
-
In
the Projects tab, right click and select Run. Run option will
compile, build and invoke the application in the default browser, let's
call it browser A1 as shown below. Enter name to join the chat
and
then enter some message. You will see the chat application
running as you have seen in exercise
1.

-
Open another browser A2, preferably with different profile or different brand of browser, and type http://localhost:8080/cometd
to access the application. Enter name to join the chat and then enter
some message.
- Open another browser B and type http://localhost:8080/cometd/ChatExternalServlet?user=me&message=hello
and hit return.
It will invoke the servlet ChatExternalServlet.
Notice user=me&message=hello
are in the HTTP
request. The following shows the
response in browser B.
The following is the
response in browser A1: me:
hello message is sent by the ChatExternalServlet
and received in client chat browser.
Browser A2 will have the same response.

-
We will add a timer service to generate some
periodic maintenance message to the chat client. In
ChatExternalServlet.java, first add the following code to
define the timer.
/**
* Push message on the chat room every 10 seconds.
*/
public ScheduledThreadPoolExecutor timer =
new ScheduledThreadPoolExecutor(1);
It will look like the
following in NetBeans IDE
- In
servlet init() method, add a timer service routine like the following
code template. You will need to complete the code based on
the
instruction in red.
This wake up message is scheduled to push to the
chat client every 10 seconds.
timer.scheduleAtFixedRate(new Runnable(){
public void run(){
CometEngine engine = CometEngine.getEngine();
CometContext context = engine.getCometContext(channel);
if (context != null) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("text", "Wake up call form the chatroom :-)");
map.put("user", "ChatMonitor");
//Construct Bayeux Data by creating the Data and add the map into it.
DeliverResponse deliverResponse = new DeliverResponse();
//Construct DeliveryResponse by setChannel, setData, setLast, setFollow, and setFinished.
try{
context.notify(deliverResponse);
} catch(IOException ex){
ex.printStackTrace();
}
}
}
}, 10, 10, TimeUnit.SECONDS);
After you have
completed the code in inti() method, it will look like the following in
NetBeans.
- One last step is to clean up the resources of the timer.
Add the following destroy() method to the servlet.
@Override
public void destroy(){
timer.shutdown();
}
With the NetBeans IDE
Now repeat the steps in
Step 3 from 2 to 5. Now you will see the timer is generating all the message to the chat client as shown below.

Summary
In this exercise, you have learned how to easily develop a servlet
to interact with the chat clients by using Grizzly Comet Framework
APIs.
Back to top
Next
exercise