I\'m trying to implement Simple chat using Servlet 3.0 and Comet pattern based on its async support.
I\'m inspired by this article: http://www.javaworld.com/javaworld/jw
You are running while loop inside contextInitialized() method which is wrong. contextInitialized() is invoked by Servlet Container as part of the application startup, having while loop there will block your app start.
Modified the code such the ContextListener will start one daemon thread which publishes the messages to the watchers
@WebListener
public class ChatPushService implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
final List watchers = new ArrayList();
sce.getServletContext().setAttribute("watchers", watchers);
// store new messages not published yet
Queue messages = new ConcurrentLinkedQueue();
sce.getServletContext().setAttribute("messages", messages);
new chatManager(sce.getServletContext()).start(); //START DAEMON
}
}
public class ChatManager implements Runnable
{
ServletContext servletCtx;
public ChatManager(ServletContext ctx)
{
this.servletCtx = ctx;
}
public void run()
{
List watchers = (List) servletCtx.getAttribute("watchers");
Queue messages = (Queue)appScope.getAttribute("messages");
Executor messageExecutor = Executors.newCachedThreadPool();
final Executor watcherExecutor = Executors.newCachedThreadPool();
while(true)
{
if(!messages.isEmpty())
{
System.out.println("notEmpty");
String message = messages.poll();
messageExecutor.execute(new Runnable(){
@Override
public void run() {
for(final AsyncContext aCtx : watchers){
watcherExecutor.execute(new Runnable(){
@Override
public void run() {
try {
aCtx.getResponse().getWriter().print("brrrrr");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
});
}
}
}
}