AJAX+js实现实时聊天

xiaoxiao2021-02-27  302

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+, 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 οnlοad="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="发送" οnclick="sendok('msginput')" /> </form> <!-- 设置一个空iframe,让表单提交后不跳转, --> <iframe width="0" height="0" style="display: none" name="sform"></iframe> </body> </html>

chatdemo_message.java package 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.jsva 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(); } } chatdemosendmsg.jsva 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(); } } } }

转载请注明原文地址: https://www.6miu.com/read-2674.html

最新回复(0)