。
当接受到新的消息时,向MessageSender中的阻塞队列ArrayBlockingQueue中put添加一条数据。当有新的数据,队列不为空时,MessageSender线程不再阻塞,会立即将消息发送到客户端浏览器。这就相当于通知MessageSender线程发送消息给客户端。
public class AjaxMessageServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
try {
// 这就相当于通知MessageSender线程发送消息给客户端
MessageSender.messages.put("[" + request.getParameter("name") + "]: " + request.getParameter("msg"));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
doPost(request, response);
}
}
3、Web前端
<script type="text/java script">
// 向HTML追加message,这个函数是给服务器向iframe中添加的java script脚本调用
function addMsg(msg) {
var msgElement = document.getElementById("msg");
msgElement.innerHTML += msg;
}
// 点击“发送”按钮后Ajax发送消息
function sendMsg() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "sendMsg"); // sendMsg是AjaxMessageServlet对应的URL
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var name = document.getElementById("input-name").value;
var msg = document.getElementById("input-msg").value;
xmlhttp.send("name=" + encodeURIComponent(name) + "&msg=" + encodeURIComponent(msg));
document.getElementById("input-msg").value = "";
}
// 服务器timeout后再重新加载iframe
function iframeRefresh() {
var iframeElement = document.getElementById("iframe");
iframeElement.src = iframeElement.src;
}
<iframe id="iframe" style="display: none;" src="comet" onload="iframeRefresh();">
姓名:
消息:
JS中,addMsg函数是提供给MessageSender中输出的js脚本来调用的,用于将消息显示在页面上。
sendMsg函数是“发送”按钮点击事件,将聊天信息发送到AjaxMessageServlet。
iframeRefresh函数是在服务器超时的时候reload重新加载iframe,timeout对服务器来说是超时,对客户端来说是加载完成,所以在iframe的onload中调用。设置timeout超时时间可以在BEGIN事件中用event.setTimeout(30*1000)或event.getHttpServletRequest().setAttribute("org.apache.tomcat.comet.timeout", new Integer(30 * 1000))来设置。
页面上的iframe设置成display: none也就是不显示,src是CometServle对应的URL,当有新的信息时,MessageSender会向iframe中输出一段JS:
out.println("<script>parent.addMsg('" + message + " ')");
浏览器加载到这段JS后会立即运行,调用addMsg函数将信息显示在页面上。
4、源码
需要DEMO源码的同学回复中留下E-mail。
作者:叉叉哥 转载请注明出处:http://blog.csdn.net/xiao__gui/article/details/38487117