- 浏览: 255778 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
lliiqiang:
软件中出错都是分类和层级的,所以错误减少不代表有进步,关键有结 ...
nio框架apache mina使用经验总结(转) -
lliiqiang:
对于整体来说有一个错误和多个错误一样,但是进度上几个错误是不同 ...
nio框架apache mina使用经验总结(转) -
lliiqiang:
最好要分离,否则相互影响的话就没有办法分离,特别是有的错误出现 ...
nio框架apache mina使用经验总结(转) -
lliiqiang:
关键是有jar包冲突,只能调整先后顺序,即自己框架的jar包是 ...
nio框架apache mina使用经验总结(转) -
baso4233:
学习了。可能会用到。
Nio 框架 Apache Mina 2 总结(自定义编解码)
根据网上一些reverse ajax例子,自己随便写了个群内聊天的例子,只实现了群聊天,其它一些杂七杂八的都没实现,写这么个功能只是学习下reverse ajax而已,了解服务器推技术。
开发工具:eclipse 3.4 纯净版
环境:tomcat 6
技术:DWR
工程类说明:
ChatManager.java 聊天实现类
Message.java 消息封装类
OnlineCounter.java 在线人数计算方法
OnlineCounterListener.java 统计在线人数
User.java 用户bean
页面:
index.jsp --输入http:127.0.0.1:8080/ichat自动访问此页面
ShowModel_Frames.jsp --登录之后群聊天的主界面
example.jsp --FCKEDIT编辑器页面
excute_sent.jsp -- 消息发送页面
online_list.jsp --在线列表页面
show_msg.jsp --显示消息页面
代码:
ChatManager.java 聊天实现类:
package com.ccic.chat; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.directwebremoting.ScriptSession; import org.directwebremoting.ServerContextFactory; import org.directwebremoting.WebContext; import org.directwebremoting.WebContextFactory; import org.directwebremoting.proxy.dwr.Util; /** * 处理聊天相关 * * * */ public class ChatManager { /** 保存当前在线用户列表 */ public static List<User> users = new ArrayList<User>(); /** * 更新在线用户列表 * @param request */ public void updateUsersList(HttpServletRequest request) { User user = null; String flag="0";//标识用户,0:不存在 1:已存在 String name= request.getSession().getAttribute("uname").toString(); String pwd= request.getSession().getAttribute("pwd").toString(); System.out.println("用户ID="+name+" 用户密码="+pwd); user = new User(pwd, name); //保存用户到列表 //如果列表中无任何用户则添加,否则循环查找列表中是否已存在该用户, //如果不存在,则添加。如果存在,则不添加 if(users.size() == 0){ users.add(user); }else{ for(int i=0;i<users.size();i++){ User us =(User)users.get(i); if(us.getUsername().equals(name)){ flag="1"; break; } } if(flag.equals("0")){ users.add(user); } } /*//统计在线人数 long count=OnlineCounter.getOnline(); StringBuffer sb=new StringBuffer(); sb.append("<script language='JavaScript' defer='defer'>"); sb.append("d = new dTree(\'d\');"); sb.append("d.add(0,-1,'在线用户列表(当前"+count+"人)');"); for(int i=0;i<users.size();i++){ User us =(User)users.get(i); sb.append("d.add("+(i+1)+",0,'"+us.getUsername()+"','','','');"); } sb.append("document.write(d);"); sb.append("d.config.useCookies=false;"); sb.append("d.config.closeSameLevel=true;"); sb.append("</script");//注意这里并不是好了“>”括号,而是在页面另有处理 System.out.println("dd="+sb.toString());*/ //将用户id和页面脚本session绑定 //this.setScriptSessionFlag(user.getUsername()); // 获得WEB上下文 WebContext wctx = WebContextFactory.get(); //获得在线列表 页面的所有脚本session Collection sessions = wctx.getScriptSessionsByPage("/ichat/pages/main/online_list.jsp"); Util util = new Util(sessions); //处理这些页面中的一些元素 //util.addFunctionCall("cBack_list", sb.toString()); util.removeAllOptions("users"); util.addOptions("users", users, "username"); } /** * 将用户id和页面脚本session绑定 * @param userid */ public void setScriptSessionFlag(String userid) { WebContextFactory.get().getScriptSession().setAttribute("userid", userid); } /** * 根据用户id获得指定用户的页面脚本session * @param userid * @param request * @return */ @SuppressWarnings("unchecked") public ScriptSession getScriptSession(String userid, HttpServletRequest request) { ScriptSession scriptSessions = null; Collection<ScriptSession> sessions = new HashSet<ScriptSession>(); sessions.addAll(ServerContextFactory.get(request.getSession().getServletContext()) .getScriptSessionsByPage("/chat/index.jsp")); for (ScriptSession session : sessions) { String xuserid = (String) session.getAttribute("userid"); if (xuserid != null && xuserid.equals(userid)) { scriptSessions = session; } } return scriptSessions; } /** * 发送消息 * @param sender 发送人 * @param msg 发送内容 * @param request 发送请求 */ public void send(String sender,String msg,HttpServletRequest request){ System.out.println("sender="+sender+" msg="+msg); LinkedList<Message> messages = new LinkedList<Message>(); if (msg != null && msg.trim().length() > 0) { //AA 说(2010-07-13): <br/>你好! messages.addFirst(new Message(sender,msg)); while (messages.size() > 3) { messages.removeLast(); } } // 获得WEB上下文 WebContext wctx = WebContextFactory.get(); //向指定页面推送消息 Collection sessions = wctx.getScriptSessionsByPage("/ichat/pages/main/show_msg.jsp"); Util utilAll = new Util(sessions); utilAll.addFunctionCall("callBack", messages); } //获得离线消息,思路:当A发消息给B时,将A用户发送的消息保存到B用户的ScriptSession中, //当B用户上线时把已经保持在B的ScriptSession中的消息读取处理并全部推送到页面。 public void getOfflineMsg(){ } }
Message.java 消息封装类
package com.ccic.chat; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.directwebremoting.Security; public class Message { DateFormat df = new SimpleDateFormat("HH:mm:ss"); private String serverTime = df.format(new Date()); private String text; private String online; public String getOnline() { return online; } public void setOnline(String online) { this.online = online; } public Message(String sender,String newtext) { text = newtext; if (text.length() > 256) { text = text.substring(0, 256); } text = sender+" 说 "+"("+serverTime+"):<br/>"+text; } public String getText() { return text; } }
OnlineCounter.java 在线人数计算方法
package com.ccic.chat; public class OnlineCounter { private static long online = 0; public static long getOnline() { return online; } public static void raise() { online++; } public static void reduce() { online--; } }
OnlineCounterListener.java 统计在线人数
package com.ccic.chat; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; /** * 统计在线用户数量 * */ public class OnlineCounterListener implements HttpSessionListener{ /** * 当SESSION创建时,自动增加 */ public void sessionCreated(HttpSessionEvent hse) { OnlineCounter.raise(); } /** * 当SESSION销毁时,自动减少 */ public void sessionDestroyed(HttpSessionEvent hse){ OnlineCounter.reduce(); } }
User.java 用户bean
package com.ccic.chat; /** * 用户 * * * */ public class User { private String password; private String username; public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public User(String password, String username) { super(); this.password = password; this.username = username; } }
index.jsp --输入http:127.0.0.1:8080/ichat自动访问此页面
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%> <!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=ISO-8859-1"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <title>Insert title here</title> <script language="javascript" type="text/javascript"> function subm(){ var uname=document.form1.username.value; var pwd=document.form1.password.value; if (uname == "") { alert("请输入用户ID"); return; } window.location="<%=request.getContextPath() %>/pages/frames/ShowModel_Frames.jsp?uname="+uname+"&pwd="+pwd; } </script> </head> <body> <form id="ff" name="form1"> <fieldset> <legend>登录</legend> <table align="center"> <tr> <td>username:</td> <td><input type="text" name="username"></td> </tr> <tr> <td>password:</td> <td><input type="text" name="password"></td> </tr> <tr align="center"> <td colspan="2"><input type="button" name="sub" value="登录" onclick="subm();"><input type="reset" name="res" value="重置"></td> </tr> </table> </fieldset> </form> </body> </html>
ShowModel_Frames.jsp --登录之后群聊天的主界面
<%@ page language="java" pageEncoding="GB2312"%> <% //(模拟)获取登录的唯一用户ID,放到SESSION供online_list.jsp加载在线用户列表 String uname = request.getParameter("uname"); uname=new String(uname.getBytes("ISO-8859-1"),"gbk"); String pwd = request.getParameter("pwd"); request.getSession().setAttribute("uname",uname); request.getSession().setAttribute("pwd",pwd); %> <html> <head> <meta HTTP-EQUIV="Pragma" CONTENT="no-cache"> <title>聊天主界面框架</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> </head> <frameset cols="*,230" frameborder="yes" border="0" framespacing="0"> <frameset rows="400,*" frameborder=yes border="5" framespacing="5"> <frame src="<%=request.getContextPath() %>/pages/main/show_msg.jsp" name="main_one" scrolling=yes noresize> <frame src="<%=request.getContextPath() %>/pages/main/excute_sent.jsp" name="main_two" scrolling=yes noresize> </frameset> <frame src="<%=request.getContextPath() %>/pages/main/online_list.jsp" name="main_top" scrolling=no noresize> </frameset> <noframes> <body> 很抱谦,您使用的浏览器不支持框架功能,请采用新版本的浏览器。 </body> </noframes> </html>
example.jsp --FCKEDIT编辑器页面
excute_sent.jsp -- 消息发送页面
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Insert title here</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <script type="text/javascript" src="<%=request.getContextPath() %>/fckeditor/fckeditor.js"></script> <script type='text/javascript' src='/ichat/dwr/interface/ChatManager.js'></script> <script type='text/javascript' src='/ichat/dwr/engine.js'></script> <script type='text/javascript' src='/ichat/dwr/util.js'></script> <script language="javascript"> /** * 发送消息 */ function send() { var sender = '<%=request.getSession().getAttribute("uname").toString() %>'; // 获得发送者名字 //var receiver = dwr.util.getValue('receiver'); // 获得接受者id var msg = getEditorHTMLContents('edt1'); // 获得消息内容 ChatManager.send(sender, msg); // 发送消息 SetEditorContents('edt1','');//清空编辑器中发送的消息 } //获取编辑器中HTML内容 function getEditorHTMLContents(EditorName) { var oEditor = FCKeditorAPI.GetInstance(EditorName); return oEditor.GetXHTML(true); } //设置编辑器中内容 function SetEditorContents(EditorName, ContentStr) { var oEditor = FCKeditorAPI.GetInstance(EditorName) ; oEditor.SetHTML(ContentStr) ; } </script> </head> <body style="margin: 0px;"> <form method="post" name="frm1"> <script type="text/javascript"> var oFCKeditor = new FCKeditor("edt1"); oFCKeditor.BasePath = "<%=request.getContextPath() %>/fckeditor/"; oFCKeditor.ToolbarSet="ichat"; oFCKeditor.Height='160'; oFCKeditor.Value=""; oFCKeditor.Create(); </script> <input type="button" value="发 送" onclick="send();"> </form> </body> </html>
online_list.jsp --在线列表页面
<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK" import="com.ccic.chat.OnlineCounter" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Insert title here</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <link rel="stylesheet" href="<%=request.getContextPath()%>/include/css/dtree.css" type="text/css"> <script src="<%=request.getContextPath()%>/include/js/dtree.js"></script> <script type='text/javascript' src='/ichat/dwr/interface/ChatManager.js'></script> <script type='text/javascript' src='/ichat/dwr/engine.js'></script> <script type='text/javascript' src='/ichat/dwr/util.js'></script> </head> <script language="javascript"> function register() { //把我输入的用户名注册到服务器 ChatManager.updateUsersList(); } //页面初始化 function init() { dwr.engine.setActiveReverseAjax(true); // 激活反转 重要 register(); } //回调函数 //function cBack_list(data){ //document.getElementById("online_list").insertAdjacentHTML("afterBegin",""); //var str="aa"+data+">"; //document.getElementById("online_list").insertAdjacentHTML("afterBegin",str); //} </script> <body onload="init();"> 在线用户列表(当前<%=OnlineCounter.getOnline() %>人): <ul id="users"> </ul> <!--<div id="online_list"> </div> --> </body> </html>
show_msg.jsp --显示消息页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Insert title here</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <script type='text/javascript' src='/ichat/dwr/interface/ChatManager.js'></script> <script type='text/javascript' src='/ichat/dwr/engine.js'></script> <script type='text/javascript' src='/ichat/dwr/util.js'></script> </head> <script language="javascript"> //页面初始化 function init() { dwr.engine.setActiveReverseAjax(true); // 激活反转 重要 } function callBack(data){ DWRUtil.addRows("tbodyId", data, cellFunctions,{escapeHtml:false}); } var cellFunctions = [ function(item) { return item.text; } ]; </script> <body onload="init();"> <table> <tbody id="tbodyId"> </tbody> </table> </body> </html>
dwr.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd"> <dwr> <allow> <convert converter="bean" match="com.ccic.chat.User"/> <create creator="new" javascript="ChatManager"> <param name="class" value="com.ccic.chat.ChatManager"/> </create> <convert converter="bean" match="com.ccic.chat.Message"/> </allow> </dwr>
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>ichat</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class> org.directwebremoting.servlet.DwrServlet </servlet-class> <init-param> <description>调试DWR,发布系统时应将其设为false</description> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <description>使用服务器推技术(反转AJAX)</description> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name> initApplicationScopeCreatorsAtStartup </param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>maxWaitAfterWrite</param-name> <param-value>100</param-value> </init-param> <load-on-startup>4</load-on-startup> </servlet> <listener> <listener-class> com.ccic.chat.OnlineCounterListener </listener-class> </listener> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> </web-app>
关于FCKEDIT编辑器,我已经删除多余的一些东西了,收集:
----------------------FCKEDIT HTML在线编辑器------------------------------ 配置:http://blog.csdn.net/xiaokuang513204/archive/2010/07/06/5715029.aspx 插件开发:http://blog.csdn.net/flying_huang/archive/2007/03/23/1539206.aspx 火狐 兼容fckedt:http://www.wangzhanweb.com/html/2010-05/231.html FCKEditor的赋值和取值操作 :http://www.blogjava.net/feingto/archive/2008/01/09/173963.html
我参考的网上两个例子,见附件!名称“chat”
一个是所有对象间聊天的,访问时对应得页面是index.jsp.
一个是点对点对象聊天的,访问时对应得页面是sample.jsp.
两者都只是简单的例子实现。
自己实现的群聊天简单例子,见附件!名称“ichat”
运行:输入http://127.0.0.1:8080/ichat/ 进入登录界面,输入“AA” 或者别的就行了。
参考:
开源的comet实现:pushlet,dwr 2.0的reverse ajax和dojo的io.bind(),
简单例子(reverse ajax):http://blog.sina.com.cn/s/blog_5bd96d520100gau4.html
谈谈webIM :http://akalius.iteye.com/blog/192727
- chat.rar (870.7 KB)
- 描述: 两个例子reverse ajax的实现
- 下载次数: 373
- ichat.rar (1.6 MB)
- 描述: 本人参照上面写的群聊天例子
- 下载次数: 509
评论
WebContext context = WebContextFactory.get();
Collection<ScriptSession> sessions = context.getScriptSessionsByPage("/dwrpush/index.jsp");
总是报空指针错误
我看你的例子比如通过WebContext实现session与userid的绑定,怎么办呢?在jsf里怎么构造WebContext呢?
Thanks
相关推荐
DWR (Direct Web Remoting) 是一个开源的Java库,它允许Web应用程序在客户端JavaScript和服务器端Java代码之间进行实时通信,类似于Ajax技术,但提供了更强大的功能。DWR 2.0版本是在DWR 1.x基础上的升级,改进了...
DWR2.0可以通过Spring的AOP支持来实现这些功能,提升应用程序的安全性和可维护性。 3. **安全性**:DWR提供了安全机制,如白名单和签名,以防止跨站脚本攻击(XSS)和跨站请求伪造(CSRF)。整合Spring后,可以通过...
DWR(Direct Web Remoting)是实现这种功能的一种技术,尤其以其独特的Reverse Ajax特性在服务器推送(Server-Sent Events, SSE,也常被称为Comet技术)领域中备受关注。下面我们将深入探讨DWR Reverse Ajax的工作...
**DWR2.0中文文档**是一本由方佳玮编著的专业技术书籍,主要涵盖了Direct Web Remoting(DWR)2.0版本的相关知识。...通过深入阅读和实践,你将能更好地利用DWR2.0实现高效的、用户友好的Web应用。
DWR(Direct Web Remoting)是一个开源的Java库,它为Web应用程序提供了强大的Ajax功能。通过DWR,前端JavaScript可以直接调用后端Java方法,从而实现动态、实时的Web交互,提升用户体验。这个主题主要围绕DWR的两个...
总的来说,通过DWR 2.0和Socket服务器的结合,我们可以构建一个高效、实时的服务器推系统,实现在Web应用中向客户端实时推送数据。这个过程涉及到Web应用的多个层面,包括服务器端的Java接口、客户端的JavaScript...
在这个“dwr3ReverseAjax示例”中,我们将深入探讨如何利用DWR 3.x版本来构建一个基于Ajax的简单Web聊天应用。 首先,DWR的核心功能是通过HTTP协议实现在客户端JavaScript和服务器端Java之间的远程方法调用(Remote...
**DWR 2.0 学习例子** ...这个"Dwr2.0学习例子"提供了实践DWR功能的机会,对于理解DWR的工作原理和提升Ajax开发技能非常有帮助。通过深入学习和实践,开发者能够更好地利用DWR的优势,提高Web应用的交互性和响应速度。
Direct Web Remoting (DWR) 是一个开源的Java库,允许Web应用程序在浏览器和服务器之间进行实时通信,绕过传统的Ajax限制。这个压缩包包含了DWR的三个关键组件:DWR3.0.jar,DWR的实例war文件,以及DWR2.0的中文说明...
在“dwr2.0最简单例子实用亲测试”中,我们可以预期这是一个关于如何使用DWR 2.0版本的入门教程,包含了实际可运行的示例代码。下面将详细介绍DWR的基本概念和在这个实例中可能涉及的关键知识点: 1. **DWR的核心...
DWR (Direct Web Remoting) 是一个开源的Java库,它允许JavaScript在浏览器端与服务器端的Java对象进行直接交互,实现动态Web应用程序的功能。DWR 2.0 是DWR的一个版本,提供了许多增强的功能和改进,以适应不断发展...
DWR2.jar提供了核心功能,DWR.xml定制了DWR的行为,DWR2.0.dtd保证了配置文件的正确性,而Web.xml确保了DWRServlet的正确部署和配置。通过熟练掌握这些知识点,开发者可以有效地利用DWR构建动态、交互性强的Web应用...
Ajax dwr驱动包 开发异步要用的 dwr中文文档
这是,以上两个版本的升级版,在原有的基础上,增加了 清空聊天记录,上线通知,用户id,及登录的所在地(ip),聊天信息可选择颜色, ps: 测试的时候记得将 info.txt(聊天信息保存文件) 绝对路径覆盖源码中,以前的路径,
DWR(Direct Web Remoting)是一种用于简化 AJAX 应用程序开发的技术。它允许客户端 JavaScript 直接调用服务器端 Java 方法,从而降低了 AJAX 编程的复杂度。DWR 的最新版本为 3.0,而其前身版本为 2.0。本文将详细...
整合DWR 2.0 和Spring 3.0 可以极大地提升Web应用的交互体验,让开发者能够更轻松地实现复杂的Ajax功能,同时保持良好的结构和可维护性。通过上述步骤,你可以创建一个演示项目,理解如何将这两个强大的工具结合在...