学习了dwr后,结合相关资料,自己写了个简单的“推”即时聊天的demo,用dwr反转实现的,期间也遇到过各种问题,通过查阅资料,终于一一解决,贴出代码,供大家分享。
一、这个是jsp页面,所有人共享这一个页面进行聊天
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'index.jsp' starting page</title>
<script type="text/javascript" src="/chart/dwr/interface/ChartManager.js"></script>
<script type="text/javascript" src="/chart/dwr/engine.js"></script>
<script type="text/javascript" src="/chart/dwr/util.js"></script>
<script type="text/javascript" src="jquery-1.4.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#register').click(function(){
if($('#username').val()==null || $('#username').val()==""){alert("请输入注册用户名!");return;}
ChartManager.updateUserList($('#username').val(),true,function(data){
if(data!=null && data!="")$('#userid').val(data);
})
});
$('#send').click(function(){
var senduser=dwr.util.getValue("username");//获取发送者姓名
var reviceuser=dwr.util.getValue("revices");//获取接收者ID
var message=dwr.util.getValue("message");//获取发送的消息内容
ChartManager.sendMessage(senduser,reviceuser,message);//dwr调用方法发送
});
});
function init(){
//页面初始化时,设置反转
dwr.engine.setActiveReverseAjax(true);
ChartManager.updateUserList(null,false);//添加当前在线人列表
}
</script>
</head>
<body>
<table>
<tr><td colspan="2"><input type="hidden" id="userid" name="userid"/></td></tr>
<tr><td colspan="2">注册用户:<input type="text" name="username" id="username"><button id="register">注册</button></td></tr>
<tr><td>接受者:<select id="revices" name="revices"></select></td>
<td><input type="text" id="message" name="message"/><button id="send">发送</button></td></tr>
<tr><td colspan="2">在线列表:<ul id="ulist"></ul></td></tr>
<tr><td colspan="2"><div style="display:none" id="showMessage"><span id="sender" style="color:bule"></span>说:<span id="msg" style="color:green"></span></div></td></tr>
</table>
<script type="text/javascript">window.onload=init;</script>
</body>
</html>
二、是聊天后天消息处理及加人
package com.chart.daoimpl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.directwebremoting.ScriptSession;
import org.directwebremoting.ServerContext;
import org.directwebremoting.ServerContextFactory;
import org.directwebremoting.WebContextFactory;
import org.directwebremoting.proxy.dwr.Util;
import com.chart.entity.UserEntity;
public class ChartDaoImpl {
private static List<UserEntity> list=new ArrayList<UserEntity>();//保存所有用户列表
/**
* 获取当前用户列表和添加用户
* flg为true,添加新用户;false 返回当前列表
*/
@SuppressWarnings("unchecked")
public String updateUserList(String uname,boolean flg,HttpServletRequest request){
UserEntity user=null;
if(flg){
//把用户sessionID当用户ID保存
user=new UserEntity(request.getSession().getId(),uname);
list.add(user);
this.SessionIdbulidsPage(user.getUserId());
}
//获取页面上下文
ServletContext context=request.getSession().getServletContext();
ServerContext serContext=ServerContextFactory.get(context);
//获取页面所有session脚本
Collection allSession=serContext.getScriptSessionsByPage("/chart/index.jsp");
// System.out.println(allSession.size());
Util util=new Util(allSession);
//移除页面在线列表 //ulist为页面列表ID属性
util.removeAllOptions("ulist");
//添加列表
util.addOptions("ulist", list, "uname");//uname为实体类用户姓名属性,ulist为页面列表id
//移除接收者
util.removeAllOptions("revices");
//添加接收者
//userId为实体类用户ID属性,uname为实体类用户姓名属性,revices为页面下拉框id
util.addOptions("revices", list, "userId", "uname");
if(!flg){return null;}
return user.getUserId();
}
//把用户ID与页面脚本绑定,一个用户ID绑定一个页面session
private void SessionIdbulidsPage(String uid){
WebContextFactory.get().getScriptSession().setAttribute("userid", uid);
}
/**
* 根据用户ID获取绑定的页面session脚本
* @param userid
* @param request
* @return
*/
@SuppressWarnings("unchecked")
public ScriptSession getScriptSession(String userid,HttpServletRequest request){
ScriptSession scriptSession=null;
Collection<ScriptSession> coll=new HashSet<ScriptSession>();
//添加该页面的所有session脚本
coll.addAll(ServerContextFactory.get(request.getSession().getServletContext()).getScriptSessionsByPage("/chart/index.jsp"));
for(ScriptSession session:coll){
String userId=(String)session.getAttribute("userid");
if(userId!=null && userId.equals(userid)){
scriptSession=session;
}
}
return scriptSession;
}
/**
* 发送消息 这里是一对一的聊天。如果要实现群发,那么直接获取页面所有session脚本进行循环群发
*/
public void sendMessage(String sendUser,String revicesUser,String msg,HttpServletRequest request){
//返回接受者已有的页面脚本session,获取页面内容
ScriptSession ss=this.getScriptSession(revicesUser, request);
Util util=new Util(ss);//把接收到的内容显示到当前用户对话界面
util.setStyle("showMessage", "display", "");
util.setValue("sender", sendUser);
util.setValue("msg", msg);
}
}
三、web.xml配置
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>
org.directwebremoting.servlet.DwrServlet
</servlet-class>
<init-param>
<!--调试模式设置true,发布时候要设置成false-->
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<description>加入dwr跨域策略(跨域调用)</description>
<param-name>crossDomainSessionSecurity</param-name>
<param-value>false</param-value><!-- false 表示允许跨域访问;true表示禁止跨域访问 -->
</init-param>
<init-param>
<description>服务器推技术(反转Ajax)激活轮询和Comet功能</description>
<param-name>activeReverseAjaxEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>开启DWR反转功能(开启“推”技术)</description>
<param-name>pollAndCometEnabled</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>告诉DWR当程序开始时初始化ReverseAjaxTracker</description>
<param-name>initApplicationScopeCreatorsAtStartup</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<description>激活页面javascript调用回调函数</description>
<param-name>allowScriptTagRemoting</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>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
四、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.jar版本不一样,这里是需要改的,dwr反转是在dwr2.0及更高版本才有的。
<dwr>
<allow>
<create javascript="ChartManager" creator="new">
<param name="class" value="com.chart.daoimpl.ChartDaoImpl"></param>
</create>
<convert match="com.chart.entity.UserEntity" converter="bean"></convert>
</allow>
</dwr>
备注:Dwr反转技术不适合做大型的聊天,它很占用服务器资源,建立的是长连接,如果别人写歌HttpClient循环访问该服务器,服务器很容易就挂掉。。 类似的推技术还有很多 比如plushlets,socket也可做推
分享到:
相关推荐
plush是可伸缩的Web应用程序,用于向移动应用程序发送推送通知。 它由两部分组成: 一个管理Web界面,用于管理用户,应用程序,设备和分析。 移动设备(用于注册自身)和第三方组件(用于发送推送通知)使用的API ...
强大,灵活和可扩展的Plush可以使编写模板变得更加容易。安装$ go get -u github.com/gobuffalo/plush用法毛绒允许将动态代码嵌入模板中。 请看以下示例: <!-- input -->< p> <%= "plush is great" %...
【华硕B85PLUSH主板集成网卡声卡显卡黑苹果驱动详解】 华硕B85PLUSH是一款基于Intel B85芯片组的主板,适用于台式机平台。这款主板集成了网卡、声卡和显卡,使得用户在搭建系统时能够享受到便捷的一体化解决方案。...
这个压缩包“华硕B85-PLUSH主板黑苹果驱动.zip”显然是为那些尝试在华硕B85-PLUS主板上安装macOS的用户准备的。下面我们将详细探讨其中涉及的关键知识点。 首先,我们要了解的是华硕B85-PLUS主板。这是一款基于...
5. 系统调试与仿真:系统在设计和开发过程中利用EDA工具(如MAx+plush)进行编译、逻辑综合和波形时序仿真。这些开发工具广泛应用于EDA领域,能够帮助开发者发现和修正设计中的错误,确保系统功能能够满足预定要求。...
- `ipconfig /all`: 显示所有适配器的完整TCP/IP配置信息,包括MAC地址、DNS服务器、DHCP租约时间等。 - `ipconfig /renew[adapter]`: 更新DHCP配置,通常用于重新获取IP地址。 - `ipconfig /release[adapter]`: ...
包含1.)XML-Viewer,用于使用3D-plush库显示3D场景。 2.)材质编辑器,允许交互式操作场景中对象的材质。 用DJGPP和Visual C ++开发。 在Dosbox和Windows中运行。
首先,Element-Plus是Element UI的升级版,它保留了Element UI的易用性和灵活性,并引入了更多现代前端技术特性,如Vue 3的支持,提供了更丰富的组件和优化的性能。在电商后台管理系统的构建中,Element-Plus的组件...
JSON.cs 通用的json编码解码,综合操作类;全新整合,测试好用,通用方法
h5 plush app输出本地日志文件
html 原生开发的5Plush sdk,通过5Plush可以调用底层的Android插件
【描述】描述中的重复字符"plush+plush+…"可能是由于输入错误或格式问题,但我们可以假设这里可能是想强调"H+"的持续升级或改进。"H+Plus"可能代表H+的一个增强版本,增加了新的功能或性能提升,这在开源项目中很...
它通过模拟系统信任的证书,使得用户能够查看和拦截应用与服务器之间的网络通信,这对于调试API调用、检测隐私泄露等问题非常有帮助。然而,由于涉及到网络安全,因此使用此类工具应当遵循合法和道德的原则,避免...
调制解调模块则涉及GMSK Modulator Baseband和GMSK Demodulator Baseband,设置BT product为0.3,符合GSM标准,同时调整其他参数如Plush length、Symbol prehistory、Phase offset和Sample persymbol,以实现调制和...
【elekkplushie_elekplush_源码】是一个关于“elek plush”纸模模型的源码项目。在IT行业中,源码是程序员用编程语言编写的原始代码,它是软件或应用程序的基础,用于控制计算机执行特定任务。在这个特定的项目中,...
带有 Adafruit Flora 的毛绒游戏控制器 带 USB 的毛绒控制器,用于与进行游戏。 固件使用来测量 Adafruit Flora 控制器上 8 个引脚的容量。 阈值设置为最小值以提高 Flora 的React时间。 如何 ...
2. **调制模块**:GMSK Modulator Baseband是实现调制的关键模块,设置包括input type(通常设为Bit)、BT product(一般为0.3,对应GSM标准)、Plush length、Symbol prehistory和Phase offset等参数。 3. **加性...
观众, but also can make the audience feel refreshed, achieving a visually pleasing feeling, making browsing the website a five-star enjoyment, thus无形中提升the level of plush dolls. To meet the ...
removable stiker 可移动性贴纸)/说明书(brochure/leaflet)/贴体包装(skin packaging)/天地盒(top and base or box with top and bottom... hinged base with extend flap)/精品盒(case box or plush box)...
面料英语专业术语是纺织行业中非常重要的知识领域,它涉及到各种布料的特性和技术细节,对于国际贸易、设计、生产和质量控制都有着至关重要的作用。以下是一些关键术语的详细解释: 1. **技术细节(Technical ...