AJAX+js实现实时聊天
了解AJAX基本流程之后,根据我们实际需要可以完成很多功能,这里我通过AJAX+javascript完成了一个简单的基于网页的实时聊天工具,代码不是很多,但是对过程的理解是最重要的,每行我都有注释,下面是代码:
首先是一个jsp网页,(html也可以)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>聊天案例</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!-- js部分,本应在一个js文件里,这里为了演示方便,放在一起 -->
<script type="text/javascript">
/* ajax生成后台访问的http对象 */
function getXmlHttpObject() {
var xmlHttp = null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest();
} catch (e) {
// Internet Explorer
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
/* ajax执行方法,访问servlet, */
function getServerInfo() {
http = getXmlHttpObject();
var url = "getmsg?time=" + Math.random();
http.onreadystatechange = getInfoBack;
http.open("GET", url, true);
http.send(null);
}
/* 消息返回执行方法, */
function getInfoBack() {
if (http.readyState == 4) {
if (http.status == 200) {
//获取返回的消息字符串
var response = http.responseText;
//通过id找到聊天显示框把消息显示出来
document.getElementById("chatbox").innerHTML += response
+ "\r\n";
//再次执行getServerInfo方法访问servlet
getServerInfo();
}
}
}
/* 点击发送按钮执行,提交表单,把输入框清空,消息显示框显示到最底部
@param o输入框的id */
function sendok(o) {
//提交表单(直接使用form表单的名字)
myform.submit();
//通过传来的输入框的id参数o把输入框的内容清空
document.getElementById(o).value = "";
//用txt保存聊天显示框的对象
var txt = document.getElementById("chatbox");
//设置显示框显示在最底部
txt.scrollTop = txt.scrollHeight;
}
</script>
</head>
<!-- 加载时就执行getServerInfo方法,监听是否有数据输入 -->
<body onload="getServerInfo()">
聊天内容:
<br>
<!-- textarae显示聊天内容,设置id方便访问该标签,设置disabled让文本框不可以输入数据,设置style背景色为白色(这些在css里设置,这里为了演示方便) -->
<textarea id="chatbox" rows="10" cols="50" disabled="disabled"
style="background-color: white;"></textarea>
<br>
<!-- 用表单来提交数据,设置name方便访问,action为servlet地址,target为跳转下面设置的页面“sform”,相当于不跳转 -->
<form name="myform" method="post" action="sendmsg" target="sform">
<!-- 输入框完成消息输入 -->
<input id="msginput" type="text" name="chatmsg" />
<!-- 发送按钮,点击执行sendok()方法 -->
<input type="button" value="发送" onclick="sendok('msginput')" />
</form>
<!-- 设置一个空iframe,让表单提交后不跳转, -->
<iframe width="0" height="0" style="display: none" name="sform"></iframe>
</body>
</html>
|
来自CODE的代码片
chatClient.jsp
然后需要一个消息对象(基于面向对象的原则)
然后需要一个加载时监听消息的servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
package chat.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import chat.classinfo.Message;
/* 监听是否有消息输入,当页面加载时就会用AJAX访问该servlet, */
public class GetMsgServlet extends HttpServlet {
// 用一个Hashtable保存正在监听消息的客户端,键为每个客户端的session,值为消息对象
public static Hashtable<String, Message> waitList = new Hashtable<String, Message>();
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/* 消息监听,如果没有消息就会等待,当发送消息的servlet执行后会释放该同步锁 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 保存Message对象
Message msg = new Message();
// 把该对象与相应的session放到Hashtable中,
waitList.put(request.getSession(true).getId(), msg);
// 消息同步,消息刚刚创建是没有任何内容的,所以一定会先进入等待状态,等到消息值放进去之后再执行后面的操作
synchronized (msg) {
try {
// 同步等待
msg.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 当执行到这一步时,就说明消息同步已被唤醒,就说明msg里面已经把消息内容放进去了。
// 设置返回编码
response.setCharacterEncoding("utf-8");
// 用pw保存返回输出对象
PrintWriter pw = response.getWriter();
// 把消息内容通过输出对象输出
pw.print(msg.getMessage());
// 把输出对象清空关闭
pw.flush();
pw.close();
}
}
|
来自CODE的代码片
chatdemo_getmsg.jsva
然后还需要一个发送时处理消息的servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
package chat.servlet;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import chat.classinfo.Message;
/* 当点击发送按钮提交表单执行该servlet,对消息进行处理 */
public class SendMsgSrevlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
/* 处理消息,把消息放进消息对象,把同步锁唤醒 */
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置传过来的数据编码
request.setCharacterEncoding("utf-8");
// 得到由输入的消息内容
String chatmsg = request.getParameter("chatmsg");
// 通过Set(Hashtable键)获取所有正在等待的session列表,方便使用迭代器
Set<String> sessions = GetMsgServlet.waitList.keySet();
// 使用迭代器Iterator方便遍历到所有的等待session
Iterator<String> sessionsIt = sessions.iterator();
// 遍历所有等待的session对象
while (sessionsIt.hasNext()) {
// 获取每一个等待的sessionid
String sessionId = sessionsIt.next();
// 通过sessionid获取该等待session的消息对象
Message msg = GetMsgServlet.waitList.get(sessionId);
// 在把输入框传过来的消息内容放进消息对象中时,可以用迭代器方便的把该等待session从等待列表中移除
sessionsIt.remove();
// 把消息内容放进消息对象,把同步消息唤醒
msg.setMessage(chatmsg);
// 同步唤醒所有正在等待的消息对象
synchronized (msg) {
msg.notifyAll();
}
}
}
}
|
来自CODE的代码片
chatdemosendmsg.jsva
最后测试一下,打开多个聊天网页
总结一下整个聊天过程:
①进入聊天页加载时就会执行监听消息的servlet,在servlet中消息同步等待
②点击发送按钮时,通过表单把输入框的内容提交到处理消息的servlet
③处理消息时就会获取所有正在等待的session和对应的消息对象,把消息内容
写进去然后同步唤醒所有等待的消息对象
④消息被同步唤醒后,把消息内容通过AJAX返回到页面
⑤获取AJAX返回的消息后显示到聊天框,并再一次执行消息监听,访问servlet
时又会等待,以此循环执行②~⑤
版权声明:博主也花了很多的心思归纳整理才分享给大家,转载请注明出处。