AJAX+js实现实时聊天

来源:互联网 发布:视频中五毛钱特效软件 编辑:程序博客网 时间:2024/05/21 14:54
chatClient.jsp<%@ 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+, SafarixmlHttp = new XMLHttpRequest();} catch (e) {// Internet Explorertry {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方法访问servletgetServerInfo();}}}/* 点击发送按钮执行,提交表单,把输入框清空,消息显示框显示到最底部@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>


chatdemo_message.javapackage chat.classinfo;/* 封装消息对象的类,这里为了演示就只设置了message一个属性 ,提供相应的set、get方法*/public class Message {private String message;public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}}

chatdemo_getmsg.jsvapackage 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 blocke.printStackTrace();}}// 当执行到这一步时,就说明消息同步已被唤醒,就说明msg里面已经把消息内容放进去了。// 设置返回编码response.setCharacterEncoding("utf-8");// 用pw保存返回输出对象PrintWriter pw = response.getWriter();// 把消息内容通过输出对象输出pw.print(msg.getMessage());// 把输出对象清空关闭pw.flush();pw.close();}}

chatdemosendmsg.jsvapackage 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方便遍历到所有的等待sessionIterator<String> sessionsIt = sessions.iterator();// 遍历所有等待的session对象while (sessionsIt.hasNext()) {// 获取每一个等待的sessionidString sessionId = sessionsIt.next();// 通过sessionid获取该等待session的消息对象Message msg = GetMsgServlet.waitList.get(sessionId);// 在把输入框传过来的消息内容放进消息对象中时,可以用迭代器方便的把该等待session从等待列表中移除sessionsIt.remove();// 把消息内容放进消息对象,把同步消息唤醒msg.setMessage(chatmsg);// 同步唤醒所有正在等待的消息对象synchronized (msg) {msg.notifyAll();}}}}





0 0