dwr实现web单聊

2024-05-05 02:38
文章标签 实现 web dwr 单聊

本文主要是介绍dwr实现web单聊,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

通过DWR实现单对单聊天,参考网络技术文章资料,非常感谢具有分享精神的技术大牛们,结合资料,做了以下技术总结:

1、下载dwr.jar

官网地址:http://directwebremoting.org/dwr/downloads/ 

下载最新版本V3.0

dwr.jar依赖commons-logging.jar,下载commons-logging.jar

2、导入jar

         将上述下载的jar 复制到web工程的WEB-INF/lib 下

3、在web.xml中加入dwr的servlet和相关配置

<!-- DWR配置 START --><servlet><servlet-name>DWRServlet</servlet-name><servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class><!-- comet方式 --><init-param><param-name>activeReverseAjaxEnabled</param-name><param-value>true</param-value></init-param><!-- polling方式:在comet方式的基础之上,再配置以下参数 --><init-param>  <param-name>org.directwebremoting.extend.ServerLoadMonitor</param-name>  <param-value>org.directwebremoting.impl.PollingServerLoadMonitor</param-value>  </init-param> <init-param><param-name>debug</param-name><param-value>false</param-value></init-param><!-- 毫秒数。页面默认的请求间隔时间是5秒 --><init-param><param-name>disconnectedTime</param-name><param-value>5000</param-value> </init-param>		<!-- 指定配置文件 --><init-param><param-name>config</param-name><!-- 如果有多个用","分开 --><param-value>/WEB-INF/classes/dwr.xml                </param-value></init-param><!-- dwr的comet控制 --><init-param><param-name>pollAndCometEnabled</param-name><param-value>true</param-value></init-param><!-- 使能够从其他域进行请求 --><init-param><param-name>crossDomainSessionSecurity</param-name><param-value>false</param-value></init-param><!-- 安全设置,允许远程js --><init-param><param-name>allowScriptTagRemoting</param-name><param-value>true</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>DWRServlet</servlet-name><url-pattern>/dwr/*</url-pattern></servlet-mapping> <servlet> <servlet-name>messageutil</servlet-name><servlet-class>com.dc.platform.action.DwrScriptSessionManagerUtil</servlet-class><load-on-startup>2</load-on-startup></servlet>	<!-- DWR配置 END -->

4DwrScriptSessionManagerUtil.java配置

/*** @description :在线用户链接监听*/
public class DwrScriptSessionManagerUtil extends DwrServlet{private static final long serialVersionUID = -7504612622407420071L;private OnlineUserService onlineUserService;public void init() throws ServletException {<span style="white-space:pre">	</span>onlineUserService = (OnlineUserService)Context.getBean("onlineUserService");ServerContext serverContext = ServerContextFactory.get();Container container = serverContext.getContainer();ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);ScriptSessionListener listener = new ScriptSessionListener() {//销毁sessionpublic void sessionDestroyed(ScriptSessionEvent event) {int userId = Integer.parseInt((String)event.getSession().getAttribute("userId"));onlineUserService.removeScriptSession(userId);}//创建sessionpublic void sessionCreated(ScriptSessionEvent event) {HttpSession session = WebContextFactory.get().getSession();User user = (User)session.getAttribute("login");user.setScriptSession(event.getSession());onlineUserService.addScriptSession(user);event.getSession().setAttribute("userId", user.getId()+"");}};// 设置监听,dwr3才有manager.addScriptSessionListener(listener);SessionContainer.container.setManager(manager);}
}

5、

调用有简单返回值的

java

方法

 

调用有简单返回值的java方法  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/dwr30.dtd">
<!-- 通用dwr配置 -->
<dwr><allow><!-- 从Spring中获取Java对象 --><create javascript="chatRoomService" creator="spring"><param name="beanName" value="chatRoomService"></param></create></allow>
</dwr>

6、页面引用以下js

<!--dwr相关  -->
<script type='text/javascript' src='dwr/engine.js'></script>
<script type='text/javascript' src='dwr/util.js'></script>
<script type='text/javascript' src='dwr/interface/chatRoomService.js'></script>  //自定义的service类方法

dwr/engine.js,dwr/util.js是固定的,是Dwr的脚本驱动Js和常用的工具类用来对返回的信息加工处理的。
dwr/interface/chatRoomService.js是用户需要直接访问的JavaBean对应的JavaScript映射。注意路径
的书写,以及相对位置,这几个文件的层次结构是固定的。并且应用在部署的时候要选择Root方式,否则找不到路径。

7、index.jsp注册当前在线人员 

$(function(){  dwr.engine.setActiveReverseAjax(true);dwr.engine.setNotifyServerOnPageUnload(true);chatRoomService.addScriptSession($("#username").val(),$("#userid").val(),function(msg){
// 		alert("登录系统");});
});

注意:    dwr.engine.setActiveReverseAjax(true);
dwr.engine.setNotifyServerOnPageUnload(true);

这个是要在使用reverse-ajax的页面必须的

8、后台service处理注册人员

/** * 添加客户端session将跳转放置dwr的回调函数中 * 登录成功后进行调用  * @param username* @param req* @return*/
public String addScriptSession(String userid, HttpServletRequest req) {  //此方法定义为上线注册,并更新所有人的在线人员列表Browser.withAllSessions(new Runnable() {private ScriptBuffer script = new ScriptBuffer();@Overridepublic void run() {Collection<ScriptSession> sessions =  Browser.getTargetSessions();Set<String> sessionUserIds = new HashSet<String>();//循环所有在线者,因一个人会有多个ScriptSession,去重String userIdStr="";for (ScriptSession scriptSession : sessions) {String sessionUserId = (String) scriptSession.getAttribute("userId");if(!sessionUserIds.contains(sessionUserId)){sessionUserIds.add(sessionUserId);userIdStr += sessionUserId + ",";}}if(userIdStr.endsWith(",")){userIdStr = userIdStr.substring(0, userIdStr.length()-1);}int sessionUserCount=0;sessionUserCount=sessionUserIds.size();String sql="select id,name from sys_user where id in ("+userIdStr+") order by sortcol asc";SEntityList userlist = baseDao.search(sql, null);String onlineusers = "";for (SEntity user : userlist) {onlineusers += "<a οnclick=setdialog("+user.getValueAsString("id")+"); id=\"onlineUsersList_"+user.getValueAsString("id")+"\" hf=\"s?opr=chatRoomService&ac=gotoNewsInformationByIndex&selectUserid="+user.getValueAsString("id")+"\" style=\"height: 16px;line-height: 16px;\" target=\"dialog\" width=\"950\" height=\"500\" resizable=\"false\" maxable=\"false\" minable=\"false\"><span class=\"onlinepeople\" style=\"display:block;height:24px;line-height:24px;\" >"+user.getValueAsString("name")+"</span><input id=\"onlineusernum\" style=\"display:none\" value=\""+sessionUserCount+"\"></a>";}script.appendCall("addOnlineUser",onlineusers);for (ScriptSession scriptSession : sessions) {//发送消息scriptSession.addScript(script);}}});return "ok";
}

9、页面显示在线人员

脚本直接接收后台返回的在线人员,显示在index.jps

//获取当前在线人列表
function addOnlineUser(user){$("#onlineusers").html(user);
}

10、发送消息

页面调用:

<div id="valcontent" class="contentBox" layoutH="13"><div class="pageFormContent"><div class="tabs" id="<%=tabId %>" currentIndex="0" eventType="click"><div id="receivercontent" class="tabsContent" style="border-style:none;"><fieldset><dl><input type="text" readonly="readonly" id="receiverName" name="receiverName" size="20"/></dl></fieldset></div></div></div><div class="topside"><div class="chatcontent"><div id="chatcontent" class="eachcontent"></div></div></div><form id="mainForm" name="mainForm">  <input type="hidden" name="rel" value="lookupAddOnlydialog"/><input type="hidden" id="userid" value="<%= user.getId()%>"><input type="hidden" id="username" value="<%= user.getName()%>"><input type="hidden" id="receiverId"><div class="bottomside" ><div class="content"><textarea id="msgText" class="msgText"></textarea>  </div><input type="button" class="send" οnclick="javascript:singlePushMsg();" value="发言"><input type="button" class="clear" οnclick="javascript:reset0();" value="清空"><input type="button" id="searchmore" class="searchmore" οnclick="javascript:searchMoreChatLog();" value="查看更多消息"></div></form>
</div>

脚本处理:

<script type="text/javascript">//单对单聊天function singlePushMsg(){var userid = $("#userid").val(); var senderName = $("#username").val(); var receiverid = $("#receiverId").val();var receiverName = $("#receiverName").val();var msgText = $("#msgText").val();if (msgText == "" || msgText.length <= 0) {     alert("请输入内容");  return;  }chatRoomService.singlePushMsg(userid,senderName,receiverName,msgText,receiverid);}
</script>


后台service处理发送消息,且接收方和发送发实时接收消息

@SuppressWarnings("unchecked")  
public void singlePushMsg(final String senderId,final String senderName, final String receiverName, final String msgText,final String receiverId) {//发送消息(在线则发送,不在线则跳过)Browser.withAllSessionsFiltered(new ScriptSessionFilter() {@Overridepublic boolean match(ScriptSession session) {String sessionUserId = null;if(session != null){sessionUserId = (String) session.getAttribute("userId");}if(senderId.equals(sessionUserId) || receiverId.equals(sessionUserId)){return true;}return false;}}, new Runnable() {private ScriptBuffer script = new ScriptBuffer();@Overridepublic void run() {script.appendCall("doReply",senderName,receiverName,msgText);boolean receiverIdOnline = false;Collection<ScriptSession> sessions =  Browser.getTargetSessions();String sessionUserId =null;for (ScriptSession scriptSession : sessions) {//发送消息scriptSession.addScript(script);sessionUserId = (String) scriptSession.getAttribute("userId");String sql="";String chatlogsql="";SEntity chatlog=new SEntity("OA_SINGLE_CHAT_LOG");//判断接收者是否在线//存储聊天记录(接收者在线则存储聊天记录当前信息标记为已读,接收者不在线则存储聊天记录当前信息标记为未读if(receiverId.equals(sessionUserId)){receiverIdOnline = true;//处理发送的消息存入数据库					if(receiverId!=null && !receiverId.equals("")){//接收人id不为空,将接收方设置成离线sql="select * from OA_USER_ONLINE where USER_ID ="+receiverId;SEntityList user_onlinelist = baseDao.search(sql, null);SEntity user_online = null;if(user_onlinelist.size()>0){user_online=user_onlinelist.get(0);if(user_online!=null){user_online.setValue("STATUS", 1);user_online.setTableName("OA_USER_ONLINE");baseDao.update(user_online);}else{sql = "insert into OA_USER_ONLINE(USER_ID,STATUS) values ("+receiverId+",1)";baseDao.save(sql, null);}}else{sql = "insert into OA_USER_ONLINE(USER_ID,STATUS) values ("+receiverId+",1)";baseDao.save(sql, null);							}}chatlog.setValue("SEND_ID", senderId);chatlog.setValue("SEND_NAME", senderName);chatlog.setValue("RECEIVER_ID", receiverId);chatlog.setValue("RECEIVER_NAME", receiverName);chatlog.setValue("SEND_TIME", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));chatlog.setValue("SEND_CONTENT", msgText);chatlog.setValue("STATUS", 1);baseDao.save(chatlog);}else{//反之设置为在线if(receiverId!=null && !receiverId.equals("")){sql="select * from OA_USER_ONLINE where USER_ID ="+receiverId;SEntityList user_onlinelist = baseDao.search(sql, null);SEntity user_online = null;if(user_onlinelist.size()>0){user_online=user_onlinelist.get(0);if(user_online==null){sql = "insert into OA_USER_ONLINE(USER_ID,STATUS) values ("+receiverId+",2)";baseDao.save(sql, null);}else{user_online.setValue("STATUS", 2);user_online.setTableName("OA_USER_ONLINE");baseDao.update(user_online);}}}chatlog.setValue("SEND_ID", senderId);chatlog.setValue("SEND_NAME", senderName);chatlog.setValue("RECEIVER_ID", receiverId);chatlog.setValue("RECEIVER_NAME", receiverName);chatlog.setValue("SEND_TIME", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));chatlog.setValue("SEND_CONTENT", msgText);chatlog.setValue("STATUS", 2);baseDao.save(chatlog);}}}});
}

页面脚本实时接收 后台推送的聊天

function doReply(senderName,receiverName,msgText){if(receiverName == null || receiverName == ""){if($("#chatcontent").length == 0){chatRoomService.deleteScriptSessionFromChatRoom($("#username").val(),function(msg){});}else{$("#chatcontent").append("<span class=\"eachcontent\"><span class=\"chatpeo\">"+senderName+"</span>: "+msgText+"</span>");}}else{$("#chatcontent").append("<span class=\"eachcontent\"><span class=\"chatpeo\">"+senderName+"</span>:"+msgText+"</span>");}$("#msgText").val("");$(".chatcontent").scrollTop($(".chatcontent")[0].scrollHeight);
}


退出系统即该人员离线

<body scroll="no" οnunlοad="logoOut()"><input type="hidden" id="userid" value="<%= user.getId()%>">
</boby>

function logoOut() {var userid = $("#userid").val(); chatRoomService.deleteScriptSession(userid,function(msg){});
};

后台处理

public void deleteScriptSession(String userid, HttpServletRequest req) {  //此方法定义为下线注消,并更新所有人的在线人员列表Browser.withAllSessions(new Runnable() {private ScriptBuffer script = new ScriptBuffer();@Overridepublic void run() {Collection<ScriptSession> sessions =  Browser.getTargetSessions();Set<String> sessionUserIds = new HashSet<String>();//循环所有在线者,因一个人会有多个ScriptSession,去重String userIdStr="";for (ScriptSession scriptSession : sessions) {String sessionUserId = (String) scriptSession.getAttribute("userId");if(!sessionUserIds.contains(sessionUserId)){sessionUserIds.add(sessionUserId);userIdStr += sessionUserId + ",";}}if(userIdStr.endsWith(",")){userIdStr = userIdStr.substring(0, userIdStr.length()-1);}String sql="select id,name from sys_user where id in ("+userIdStr+") order by sortcol asc";SEntityList userlist = baseDao.search(sql, null);String onlineusers = "";for (SEntity user : userlist) {onlineusers += "<a οnclick=setdialog("+user.getValueAsString("id")+"); id=\"onlineUsersList_"+user.getValueAsString("id")+"\" hf=\"s?md=oa070201&ac=gotoNewsInformationByIndex&selectUserid="+user.getValueAsString("id")+"\" style=\"height: 16px;line-height: 16px;\" target=\"dialog\" width=\"950\" height=\"500\" resizable=\"false\" maxable=\"false\" minable=\"false\"><span class=\"onlinepeople\" style=\"display:block;height:24px;line-height:24px;\" >"+user.getValueAsString("name")+"</span></a>";}script.appendCall("addOnlineUser",onlineusers);for (ScriptSession scriptSession : sessions) {//发送消息scriptSession.addScript(script);}}});
}

页面展示



这篇关于dwr实现web单聊的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/960640

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Java Web指的是什么

Java Web指的是使用Java技术进行Web开发的一种方式。Java在Web开发领域有着广泛的应用,主要通过Java EE(Enterprise Edition)平台来实现。  主要特点和技术包括: 1. Servlets和JSP:     Servlets 是Java编写的服务器端程序,用于处理客户端请求和生成动态网页内容。     JSP(JavaServer Pages)

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

BUUCTF靶场[web][极客大挑战 2019]Http、[HCTF 2018]admin

目录   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 [web][HCTF 2018]admin 考点:弱密码字典爆破 四种方法:   [web][极客大挑战 2019]Http 考点:Referer协议、UA协议、X-Forwarded-For协议 访问环境 老规矩,我们先查看源代码

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、