わっっかんない。

家で試すよう。
コメット。

クライアント側

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>CometChatSender</title>
<script type="text/javascript" src="./js/common.js"></script>
</head>

<body>
	<div id="talk"></div>
	<form method="post"  action="/">
	ユーザ名:<input type="text" name="user"  size="20" id="user"/>
	メッセージ:<input type="text" name="message"  size="60"  id="message"/>
	<input type="button" value="送信"  size="60"
		onclick="postMessage('./CometServlet', true,user.value, message.value)"/>

	</form>
</body>

</html>

function createHttpRequest() {

    if(window.ActiveXObject){
        try {
            // MSXML2
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                // MSXML
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e2) {
                return null;
            }
        }

    } else if(window.XMLHttpRequest){
        return new XMLHttpRequest();
    } else {
        return null;
    }
}

function postMessage(fileName , async ,user , message ) {
    var request = createHttpRequest();

    request.open( 'POST' , fileName , async );
    request.setRequestHeader('Content-Type',
        'application/x-www-form-urlencoded; charset=UTF-8');

    request.onreadystatechange = function() {
        if (request.readyState ==4) {
        	if(request.status == 200){
        		if(request.responseText){
        			document.getElementById("talk").innerHTML += request.responseText;
        		}
        		postMessage('./CometServlet', true);
        	}
        }
    }

    request.send( 'user=' + user + '&message=' + message );
}


import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

/**
 * Servlet implementation class CometServlet
 */
public class CometServlet extends HttpServlet implements  CometProcessor{
	private static final long serialVersionUID = 1L;

	//protected ArrayList<HttpServletResponse> connections = new ArrayList<HttpServletResponse>();
	protected MessageSender messageSender = null;

	public void init() throws ServletException{
		messageSender = new MessageSender();
		Thread messageSenderThread =
			new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() +"]");
		messageSenderThread.setDaemon(true);
		messageSenderThread.start();
	}

	public void destroy(){
		messageSender.stop();
		messageSender = null;
	}

    /**
     * @see HttpServlet#HttpServlet()
     */
    public CometServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	@Override
	public void event(CometEvent cometevent) throws IOException, ServletException {
		HttpServletRequest request = cometevent.getHttpServletRequest();
		HttpServletResponse response = cometevent.getHttpServletResponse();

		if ( cometevent.getEventType() == CometEvent.EventType.BEGIN ){
			cometevent.setTimeout(60 * 1000 * 30);
			log("begin for session: " + request.getSession(true).getId());

			/*
			response.setContentType("text/html;charset=UTF-8");
			PrintWriter out = response.getWriter();
			out.println("<!doctype html public \"-//w3c//dtd html" + " 4.0 transitional//en\">");
			out.println("<head><title>チャットメッセージ</title>" + "</head><body bgcolor=\"#FFFFFF\">");
			out.println("</body></html>");
			out.flush();
			*/

			messageSender.setConnection(response);

			return ;

		}  else if (cometevent.getEventType() == CometEvent.EventType.END) {
			log("End for session: " + request.getSession(true).getId());
			/*
			PrintWriter out = response.getWriter();
			out.println("</body></html>");
			*/
			cometevent.close();
			return ;
		}

		if ("POST".equals(request.getMethod())){
			final String user = request.getParameter("user");
			final String message = request.getParameter("message");

			if( !user.equals("undefined") || !message.equals("undefined")){
				messageSender.send(user, message);
			}

			return;
		}
	}

	public class MessageSender implements Runnable {
		protected boolean running = true;
		protected ArrayList<String> messages = new ArrayList<String>();
		private ArrayList<ServletResponse> connections = new ArrayList<ServletResponse>();

		private synchronized void setConnection(final ServletResponse res){
			connections.add(res);
			notify();
		}

		public MessageSender(){}

		public void stop(){
			running = false;
		}

		public void send(final String user, String message){
			synchronized (messages) {
				messages.add("[" + user + "]:" + message);
				messages.notify();
			}
		}

		@Override
		public void run() {
			while(running){
				if(messages.size() == 0){
					try{
						synchronized (messages) {
							messages.wait();
						}
					}catch(InterruptedException e){
						// ignore
					}

				}

				String[] pendingMessage = null ;
				synchronized (messages) {
					pendingMessage = messages.toArray(new String[0]);
				}
				messages.clear();

				try{
					if (connections == null){
						try{
							synchronized (this) {
								wait();
							}
						}catch(InterruptedException e){
							// ignore
						}
					}

					for(final ServletResponse connection : connections){
						PrintWriter out = connection.getWriter();

						for(final String m : pendingMessage){
							out.println(m + "<br/>");
						}

						out.flush();
						out.close();
					}

					connections.clear();

				} catch(IOException e){
					log("IOException sending message", e);
				}

			}
		}

	}

}