利用的是一种默认的配置。
User和Message是2个Javabean,封装用户及消息数据。
ChatLogon负责登录后跳转到聊天页面。
Chat聊天的主类。
如下是具体代码:
User.java:
package com.dwr.chat.demo; public class User { private String userId; private String area; public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } }
Message.java:
package com.dwr.chat.demo; public class Message { private String from; private String to; private String msg; private String area; public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public String getArea() { return area; } public void setArea(String area) { this.area = area; } }
ChatLogon.java:
package com.dwr.chat.demo; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * Servlet implementation class ChatLogon */ public class ChatLogon extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public ChatLogon() { super(); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String userId = request.getParameter("userId"); String area = request.getParameter("area"); if (userId == null || "".equals(userId) || area == null || "".equals(area)) { response.sendRedirect("/chat/jsp/logon.jsp"); } else { HttpSession session = request.getSession(); User user = new User(); user.setArea(area); user.setUserId(userId); session.setAttribute("user", user); request.getRequestDispatcher("/chat/jsp/chat.jsp").forward(request, response); } } }
Chat.java:
package com.dwr.chat.demo; import java.util.Collection; import javax.servlet.http.HttpSession; import org.directwebremoting.ScriptBuffer; import org.directwebremoting.ScriptSession; import org.directwebremoting.WebContext; import org.directwebremoting.WebContextFactory; public class Chat { public void sendMsg(String msg, String to) { WebContext context = WebContextFactory.get(); HttpSession session = context.getSession(); ScriptSession ss = context.getScriptSession(); Collection<ScriptSession> sess = context.getAllScriptSessions(); System.out.println("sess length:" + sess.size()); if (msg == null || "".equals(msg)) { return; } session.setAttribute("flag", session.hashCode()); ss.setAttribute("flag", session.hashCode()); User user = (User) session.getAttribute("user"); if (ss.getAttribute("user") == null) { ss.setAttribute("user", user); } Message message = new Message(); message.setFrom(user.getUserId()); message.setMsg(msg); message.setTo("".equals(to) ? "所有人" : to); message.setArea(user.getArea()); ScriptBuffer sbf = new ScriptBuffer(); sbf.appendScript("Chat.recvMsg("); sbf.appendData(message); sbf.appendScript(");"); // 是否有这个人 boolean hasThisPerson = true; // 是否可以私聊 boolean isPPOk = false; // 是否在同一区域。 boolean isInSameArea = true; ScriptSession ssTo = null; // 是否是与自己聊天 boolean isWithSlef = false; for (ScriptSession ssr : sess) { if (ssr != null) { User user2 = (User) ssr.getAttribute("user"); if (user2 != null) { if ("".equals(to)) { // 发送信息给所有人。 ssr.addScript(sbf); System.out.println("发送给所有人。"); } else { if (user2.getArea().equals(user.getArea())) { if (user2.getUserId().equals(to)) { // 如果是自己,则不能进行私聊 if (user2.getUserId().equals(user.getUserId())) { isWithSlef = true; break; } else { ssTo = ssr; // 私聊 isPPOk = true; break; } } else { // 没有这个人呢。 hasThisPerson = false; break; } } else { isInSameArea = false; // 用户与您不在同一区域 break; } } } } } if (!hasThisPerson) {// 没有这个人。 ss.addScript(new ScriptBuffer(// 不能return "alert('对不起,没有这个人!');")); System.out.println("对不起,没有这个人!"); } if (!isInSameArea) { ss.addScript(new ScriptBuffer("alert('" + to + "与您不在同一区域!');")); System.out.println("不再同一个区域。。。"); } if (isPPOk) { // 私聊 ssTo.addScript(sbf); // 同时,发给自己 ss.addScript(sbf); System.out.println("私聊。"); // 不能return ssTo = null; } if (isWithSlef) { ss.addScript(new ScriptBuffer("alert('自己不能跟自己聊天!');")); System.out.println("自己不能跟自己聊天。");// 不能return } } public void exitPage() { WebContext context = WebContextFactory.get(); HttpSession ses = context.getSession(); if (ses.getAttribute("flag") != null) { int flag = (Integer) ses.getAttribute("flag"); Collection<ScriptSession> colls = context.getAllScriptSessions(); for (ScriptSession ss : colls) { if (ss != null) { if ((Integer) ss.getAttribute("flag") == flag) { ss.invalidate(); return; } } } } } }
Chat.js:
var Chat = new function() { this.sendMsg = function(){ var msg = document.getElementById("msg").value; var pp = document.getElementById("pps"); if (pp.checked) { // 如果选中复选框,说明是私聊。 pp = document.getElementById("pp").value; } else { pp = ""; } if (msg !== "") { ChatServer.sendMsg(msg,pp); document.getElementById("msg").value = ""; } else { alert("发送的消息不能为空!"); return; } }; this.recvMsg = function(data) { var dd = document.getElementById("msgCenter"); if (data !== null) { var tr = document.createElement("tr"); var td1 = document.createElement("td"); var td2 = document.createElement("td"); var td3 = document.createElement("td"); var td4 = document.createElement("td"); td1.innerText = dd.rows.length; td2.innerText = data.from; td3.innerText = data.to; td4.innerText = data.msg; tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3); tr.appendChild(td4); dd.appendChild(tr); } }; this.keySendMsg = function(e) { e = e || event; if (e.keyCode == 10) { sendMsg(); } }; // 在选中私聊复选框时,显示 this.showOrHidePP = function(oItem) { var pp = document.getElementById("pp"); if (oItem.checked) { pp.style.display = "block"; } else { pp.style.display = "none"; } }; };
Login.jsp:
<%@ page language="java" contentType="text/html; charset=gb18030" pageEncoding="gb18030"%> <!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=gb18030"> <title>logon</title> <link href="../css/global.css"></link> </head> <body> <fieldset style="width: 600px;"> <legend>用户登录</legend> <form action="/dwr/chat/logon.action" method="post"> <table width="500px" cellpadding="0" cellspacing="0"> <tr> <td>用户ID:</td> <td><input type="text" name="userId"> </td> </tr> <tr> <td>区域:</td> <td><input type="radio" name="area" value="etc01" checked="checked">电信一区 <input type="radio" name="area" value="etc02">电信二区</td> </tr> <tr align="center"> <td colspan="2"><input type="submit" value="登录系统"> </td> </tr> </table> </form> </fieldset> </body> </html>
chat.jsp:
<%@ page language="java" contentType="text/html; charset=gb18030" pageEncoding="gb18030"%> <%@page import="com.dwr.chat.demo.User"%> <!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=gb18030"> <title>chat</title> <link href="../css/global.css"></link> <script type="text/javascript" src="/dwr/dwr/engine.js"></script> <script type="text/javascript" src="/dwr/dwr/util.js"></script> <script type="text/javascript" src="/dwr/dwr/interface/ChatServer.js"></script> <script type="text/javascript" src="/dwr/chat/js/chat.js"></script> <script type="text/javascript"> window.onunload = ChatServer.exitPage(); document.onunload = ChatServer.exitPage(); </script> </head> <body onload="dwr.engine.setActiveReverseAjax(true);ChatServer.sendMsg('','');"> <div> <% User user = (User)session.getAttribute("user"); %> <span style="color:red;font-size:15px;">欢迎<%=user==null?"":user.getUserId() %></span> </div> <div style="width:500px;"> <fieldset> <legend>输入内容</legend> <input type="checkbox" id="pps" onclick="Chat.showOrHidePP(this);">私聊<input type="text" id="pp" style="display:none;"> <table width="500px" cellpadding="0" cellspacing="0"> <tr> <td>输入消息:</td> <td><textarea rows="8" cols="55" id="msg" name="msg"></textarea> </td> </tr> <tr align="center"> <td colspan="2"><input type="button" value="发送" onclick="Chat.sendMsg();"> </td> </tr> </table> </fieldset> </div> <div style="width:500px;"> <fieldset> <legend>消息中心:</legend> <table width="500px" cellpadding="0" cellspacing="0" id="msgCenter" border="1"> <tr> <td>编号</td> <td>发信人</td> <td>收信人</td> <td>消息内容</td> </tr> </table> </fieldset> </div> </body> </html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>dwr</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>crossDomainSessionSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>allowScriptTagRemoting</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <servlet> <description></description> <display-name>ChatLogon</display-name> <servlet-name>ChatLogon</servlet-name> <servlet-class>com.dwr.chat.demo.ChatLogon</servlet-class> </servlet> <servlet-mapping> <servlet-name>ChatLogon</servlet-name> <url-pattern>/chat/logon.action</url-pattern> </servlet-mapping> </web-app>
dwr.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://www.getahead.ltd.uk/dwr/dwr20.dtd"> <dwr> <allow> <create creator="new" javascript="ChatServer"> <param name="class" value="com.dwr.chat.demo.Chat"></param> </create> <convert converter="bean" match="com.dwr.chat.demo.User"></convert> <convert converter="bean" match="com.dwr.chat.demo.Message"></convert> </allow> </dwr>