本文主要是介绍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 -->
4、DwrScriptSessionManagerUtil.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单聊的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!