dwr3实现的在线客服.

最近公司想要给公司的网站上添加一个在线客服功能,不让使用第三方插件只能自己制作.于是上网上找些例子,http://blog.csdn.net/luojia_wang/article/details/8825929给了不小的启发.推送技术基本是其之上改进的,非常感谢. 基于dwr3的在线客服系统

der.xml配置文件,跟web.xml在一层下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 3.0//EN" "http://getahead.org/dwr/dwr30.dtd">  
<dwr>
	<allow>
		<create creator="new" javascript="MessagePush">
			<param name="class" value="com.dwr.service.MessagePush"/>
		</create>
		<create creator="new" javascript="SendMessage">
			<param name="class" value="com.dwr.service.SendMessage"/>
		</create>
	</allow>
</dwr>

web.xml

<!-- application监听 -->
	<listener>
		<listener-class>com.dwr.listener.MyApplicationListener</listener-class>
	</listener>
	<!-- session监听 -->
	<listener>
		<listener-class>com.dwr.listener.MySessionListener</listener-class>
	</listener>
	
  <servlet>
  	<servlet-name>dwr-invoker</servlet-name>
  	
    <servlet-class>
        org.directwebremoting.servlet.DwrServlet
    </servlet-class>
    
    <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>
    
    <init-param>
      <param-name>classes</param-name>
      <param-value>java.lang.Object</param-value>
    </init-param>
    
    <init-param>
        <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>3000</param-value>
    </init-param>
    
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
    
    <init-param>
        <param-name>logLevel</param-name>
        <param-value>WARN</param-value>
    </init-param>
  </servlet>
  <servlet>
    <servlet-name>LoginAction</servlet-name>
    <servlet-class>com.dwr.login.LoginAction</servlet-class>
  </servlet>


  <servlet-mapping>
	<servlet-name>dwr-invoker</servlet-name>
	<url-pattern>/dwr/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>LoginAction</servlet-name>
    <url-pattern>/login.do</url-pattern>
  </servlet-mapping>


信息发送模块,

/**
 * 信息发送模块
 * @author Joker
 *
 */
public class SendMessage {

	private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd   HH:mm:ss");
	private Date date = new Date();
	/**
	 * userId: 被推送页面ID, otherId: 对方页面Id, message:发送内容
	 */
	public void sendMessage(final String userId, final String otherId, final String message, String user){
		System.out.println("sendMessage()==>userId:" + userId + "\t otherId:" + otherId + "\t message:" + message + "\t userName:" + user);
		if(user == null){
			user = "系统提示   " + format.format(date);
		}else{
			user += format.format(date);
		}
		
		final String autoMessage = "{\"otherId\":\""+otherId+"\",\"message\":\""+message+"\",\"userName\":\""+user+"\"}";
		
		Browser.withAllSessionsFiltered(new ScriptSessionFilter(){

			public boolean match(ScriptSession session) {
				
				if(session.getAttribute("userId") == null)
					return false;
				else
					return session.getAttribute("userId").equals(userId);
			}
			
		}, new Runnable(){

			ScriptBuffer script = new ScriptBuffer();
			public void run() {
					script.appendCall("showMessage", autoMessage);
					
				Collection<ScriptSession> sessions = Browser.getTargetSessions();
				
				for(ScriptSession scriptSession : sessions){
					scriptSession.addScript(script);
				}
				
			}
			
		});
	}
}
/**
 * 创建相应的ScriptSession
 * @author Joker
 *
 */
public class MessagePush implements Comparator<User>{

	/**
	 * 创建ScriptSession
	 * (k-客服,f-访客,m-发送的是对话,i-发送的是对方的Id);
	 */
	@SuppressWarnings("unchecked")
	public void onLoadPage(String userId, String identity){
		System.out.println("onLoadPage()==>userId:" + userId + "\t identity:" + identity);
		SendMessage sendMessage = new SendMessage();
		
		ScriptSession scriptSession  = WebContextFactory.get().getScriptSession();
		scriptSession.setAttribute("userId", userId);
		
		DwrScriptSessionManagerUtil dwrScriptSessionMessageUtil = new DwrScriptSessionManagerUtil();
		dwrScriptSessionMessageUtil.init(userId);
		
		if("f".equals(identity)){//判断为访客
			User user = getUser();
			if(user.getId() == null){
				//客服轮空
				sendMessage.sendMessage(userId, null, "客服正忙请稍等", null);
			}else{
				//当值客服
				sendMessage.sendMessage(userId, user.getId().toString(),  user.getId() + "号客服为您服务!", null);//发送给访客
				sendMessage.sendMessage(user.getId().toString(), userId, null, null);//发送给当值客服
				
				HttpSession session = WebContextFactory.get().getSession();
				session.setAttribute(userId, user);
				
				ServletContext application = WebContextFactory.get().getServletContext();
				Hashtable<Long, Object> ht = (Hashtable<Long, Object>)application.getAttribute("userList");
				user.setCount(user.getCount() + 1);
				ht.put(user.getId(), user);
			}
		}
	}
	
	/**
	 * 获取客服
	 */
	@SuppressWarnings("unchecked")
	public User getUser(){
		ServletContext application = WebContextFactory.get().getServletContext();
		Hashtable<Long, Object> ht = (Hashtable<Long, Object>)application.getAttribute("userList");
		Set<Long> keys = ht.keySet();
		List<User> users = new ArrayList<User>();
		for(Long key : keys){
			User user = new User();
			user = (User)ht.get(key);
			if(user.getCount() == 0){
				return user;
			}
			if(user.getCount() == 10){//阀值跳过
				continue;
			}
			users.add(user);
		}
		if(users.size() == 0){
			return new User();
		}
		
		Collections.sort(users,new MessagePush());
		
		return users.get(0);
	}
	
	/**
	 * 比较器
	 */
	public int compare(User o, User t) {
		
		if(o.getCount() > t.getCount()){
			return 1;
		}else if(o.getCount() == t.getCount()){
			if(o.getId() > t.getId()){
				return 1;
			}else if(o.getCount() == t.getCount()){
				return 0;
			}else{
				return -1;
			}
		}else{
			return -1;
		}
	}
}

public class DwrScriptSessionManagerUtil {

	public void init(final String userId){
		Container container = ServerContextFactory.get().getContainer();
		ScriptSessionManager manager = container.getBean(ScriptSessionManager.class);
		ScriptSessionListener listener = new ScriptSessionListener(){

			public void sessionCreated(ScriptSessionEvent event) {
				
				event.getSession().setAttribute("userId", userId);
			}

			@SuppressWarnings("unchecked")
			public void sessionDestroyed(ScriptSessionEvent event) {
				String userid = (String) event.getSession().getAttribute("userId");
				HttpSession session = WebContextFactory.get().getSession();
				
				User user = (User)session.getAttribute(userid);
				if(user != null){
					ServletContext application = WebContextFactory.get().getServletContext();
					Hashtable<Long, Object> ht = (Hashtable<Long, Object>)application.getAttribute("userList");
					if(user.getCount() <= 0){
						user.setCount(0L);
					}else{
						user.setCount(user.getCount() - 1);
					}
					ht.put(user.getId(), user);
				}
			}};
			
			manager.addScriptSessionListener(listener);
	}
}

application监听,用来储存在线客服
/**
 * application监听
 * @author Joker
 *
 */
public class MyApplicationListener implements ServletContextListener {
	
	private Hashtable<Long, Object> ht = new Hashtable<Long, Object>();
	public void contextDestroyed(ServletContextEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void contextInitialized(ServletContextEvent event) {
		System.out.println("项目初始化()...");
		ServletContext application = event.getServletContext();
		application.setAttribute("userList", ht);
	}

}
/**
 * session监听
 * @author Joker
 *
 */
public class MySessionListener implements HttpSessionListener {

	public void sessionCreated(HttpSessionEvent arg0) {
		// TODO Auto-generated method stub

	}

	@SuppressWarnings("unchecked")
	public void sessionDestroyed(HttpSessionEvent event) {
		User user = (User)event.getSession().getAttribute("user");
		if(user != null){
			ServletContext application = WebContextFactory.get().getServletContext();
			Hashtable<Long, Object> ht = (Hashtable<Long, Object>)application.getAttribute("userList");
			ht.remove(user.getId());
		}
	}

}
客服页面
<%@ 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>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<script type='text/javascript' src='js/jquery-1.5.1.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/engine.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/interface/MessagePush.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/interface/SendMessage.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/util.js'></script>
		<title>客服页面</title>
		<style type="text/css">
			#all_div{width: 1440px; height: 690px; border:1px solid red;}
			#left_div{width: 75%; height: 100%; float: left; border-right: 1px solid red}
			#right_div{width: 24.5%; height: 100%; float: left}
			
		</style>
		<script type="text/javascript">
			$(function(){
				dwr.engine.setActiveReverseAjax(true);
				dwr.engine.setNotifyServerOnPageUnload(true);
				MessagePush.onLoadPage(${user.id}, "k");
			});
			
			function showMessage(data){
				var arr = jQuery.parseJSON(data);
				var callerId = arr.otherId;
				var message = arr.message;
				var userName = arr.userName;
				if($("#" +callerId + "div").length == 0){
					$("#right_div").append("<a href=\"javascript:add_div("+callerId+");\">新访客:"+callerId+"</a><br/>");
				}
				var old_message = $("#" +callerId + "div").find(".show_message").find("textarea").val();
				$("#" +callerId + "div").find(".show_message").find("textarea").val(old_message + "\r" + userName + "\r " + message);
			};
			
			function sendMessage(div_Id){
				var old_message = $("#" + div_Id).find(".show_message").find("textarea").val();
				var new_message = $("#" + div_Id).find(".send_message").find("textarea").val();	
				SendMessage.sendMessage(div_Id.substring(0, div_Id.length-3), ${user.id}, new_message, "客服("+${user.id}+")" );
				$("#" + div_Id).find(".show_message").find("textarea").val(old_message + "\r客服("+${user.id}+")\t"+getNowFormatDate()+":\r " + new_message);
				$("#" + div_Id).find(".send_message").find("textarea").val("");
			};
			
			function close_div(div_Id){
				$("#" + div_Id).remove();
			};
			
			function add_div(callerId){
				if($("#" +callerId + "div").length == 0){
					var new_div = $(".message_box").clone();
					new_div.attr("id", callerId + "div");
					new_div.removeClass("message_box");
					new_div.find(".box_title").append("<span style=\"line-height: 25px;\">[新访客:"+callerId+"]</span><span style=\"display: block; line-height: 25px; float: right; cursor: pointer;\" οnclick=\"close_div('"+callerId+"div')\">[关闭]</span>");
					new_div.find(".send_message").append("<img class=\"send_button\" src=\"images/send.jpg\" style=\"width: 16%; height: 99%; cursor: pointer;\" οnclick=\"sendMessage('"+callerId+"div')\"/>");
					$("#left_div").append(new_div);
					new_div.show();
				}
			}
			
			function getNowFormatDate() {
				var day = new Date();
				var Year = 0;
				var Month = 0;
				var Day = 0;
				var Hour = 0;
				var Minute = 0;
				var Second = 0;
				var CurrentDate = "";
				   //初始化时间
				   //Year       = day.getYear();//有火狐下2008年显示108的bug
				   Year       = day.getFullYear();//ie火狐下都可以
				   Month      = day.getMonth()+1;
				   Day        = day.getDate();
				   Hour       = day.getHours();
				   Minute     = day.getMinutes();
				   Second     = day.getSeconds();
				   
				   CurrentDate += Year + "-";
				   
				   if (Month >= 10 ){
				    CurrentDate += Month + "-";
				   }else{
				    CurrentDate += "0" + Month + "-";
				   }
				   if (Day >= 10 ){
				    CurrentDate += Day + " ";
				   }else{
				    CurrentDate += "0" + Day ;
				   }
				   
				   if (Hour >= 10 ){
				    CurrentDate += Hour + ":";
				   }else{
				    CurrentDate += "0" + Hour + ":" ;
				   }
				   if (Minute >= 10 ){
				    CurrentDate += Minute + ":";
				   }else{
				    CurrentDate += "0" + Minute + ":" ;
				   }
				   if (Second >= 10 ){
				    CurrentDate += Second ;
				   }else{
				    CurrentDate += "0" + Second ;
				   }
				   return CurrentDate;
				}
		</script>
	</head>
	<body>
		客服编号:<input name="userId" value="${user.id}"/>
		客服名称:<input name="userId" value="${user.name}"/>
		<div id="all_div"> 
			<div id="left_div"></div>
			<div id="right_div"></div>
		</div>
	</body>
	<div class="message_box" style="width: 55%; height: 60%; border: 4px solid black; display: none">
		<div class="box_title" style="width: 100%; height: 25px; background-color: #ACFFF0;">
		</div>
		<div class="show_message" style="width: 100%; height: 73%; border-bottom: 2px solid blue;">
			<textarea style="width: 99%; height: 99%" readonly="readonly"></textarea>
		</div>
		<div class="send_message" style="width: 100%; height: 20%; border-bottom: 2px solid blue;">
			<textarea style="width: 80%; height: 93%"></textarea>
		</div>
	</div>
</html>
访客页面

<%@ 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>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<script type='text/javascript' src='js/jquery-1.5.1.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/engine.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/interface/MessagePush.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/interface/SendMessage.js'></script>
		<script type='text/javascript' src='/web_dwr/dwr/util.js'></script>
		<title>访客页面</title>
		<style type="text/css">
			body{margin:0px;background:#FFF;overflow:hidden; font-size:12px}
			body img{ display:block;}
			.lt{ padding-right:139px;}
			.lt_top{ height:48px; background:url(images/zx_03.jpg);}
			.lt_top .l{ float:left;}
			.lt_top .r{ float:right;}
			.lt_top span{ float:left; padding:20px 0px 0px 6px; color:#000; color:#404799;}
			.lt_main{ padding-left:9px; background:url(images/zx_10.jpg) left repeat-y;padding-right:9px; position:relative;}
			.lt_main .text{ padding:5px; overflow:auto; background:#eee;font-size:14px; border:0px; width:99%;}
			.lt_main .kz{ position:absolute;right:0px;top:0px; width:11px; background:url(images/zx_16.jpg);}
			.lt_main .kz img{ position:absolute;top:50%; margin-top:-24px; cursor:pointer;}
			.lt_xx{ background:url(images/zx_18.jpg); height:110px; position:relative; padding:29px 100px 0px 12px;}
			.lt_xx .l{ position:absolute;left:0px;top:0px;}
			.lt_xx textarea{ border:0px; overflow:auto; width:99%;height:80px; font-size:14px; padding:2px;}
			.lt_xx .an{ position:absolute;right:0px;top:0px; cursor:pointer;}
			.lt_right{ position:absolute;right:0px;top:0px; height:400px; width:139px; background:url(images/zx_12.jpg);}
			.lt_right .t{ position:absolute;top:0px;right:0px;}
			.lt_right .tu{ position:absolute;top:94px;right:7px;}
			.lt_right .b{ position:absolute; bottom:0px;right:0px;}
		</style>
		<script type="text/javascript">
			var userId = Math.random().toString().substr(2, 11);
			$(function(){
				var h = $(window).height();
				$(".lt_main .text").css("height",h-197);
				$(".lt_main .kz").css("height",h-187);
				$(".lt_right").css("height",h);
				$(window).resize(function(){
			   		h = $(window).height();
					$(".lt_main .text").css("height",h-197);
					$(".lt_main .kz").css("height",h-187);
					$(".lt_right").css("height",h);
				});
			});
			
			$(function(){
				dwr.engine.setActiveReverseAjax(true);
				dwr.engine.setNotifyServerOnPageUnload(true);
				MessagePush.onLoadPage(userId, "f");
			})
			
			function showMessage(date){
				var arr = jQuery.parseJSON(date);
				var callerId = arr.otherId;
				var message = arr.message;
				var userName = arr.userName;
				var old_message = $("[name=\"show_message\"]").val();
				$("[name=\"callerId\"]").val(callerId);
				$("[name=\"show_message\"]").val(old_message + "\r" + userName + "\r " + message);
			};
			
			function sendMessage(){
				var callerId = $("[name=\"callerId\"]").val();
				var new_message = $("[name=\"send_message\"]").val();
				var old_message = $("[name=\"show_message\"]").val();
				SendMessage.sendMessage(callerId, userId, new_message, "访客("+userId+")");
				$("[name=\"show_message\"]").val(old_message + "\r访客("+callerId+")\t"+getNowFormatDate()+":\r " + new_message);
				$("[name=\"send_message\"]").val("");
			};
			
			function getNowFormatDate() {
				var day = new Date();
				var Year = 0;
				var Month = 0;
				var Day = 0;
				var Hour = 0;
				var Minute = 0;
				var Second = 0;
				var CurrentDate = "";
				   //初始化时间
				   //Year       = day.getYear();//有火狐下2008年显示108的bug
				   Year       = day.getFullYear();//ie火狐下都可以
				   Month      = day.getMonth()+1;
				   Day        = day.getDate();
				   Hour       = day.getHours();
				   Minute     = day.getMinutes();
				   Second     = day.getSeconds();
				   
				   CurrentDate += Year + "-";
				   
				   if (Month >= 10 ){
				    CurrentDate += Month + "-";
				   }else{
				    CurrentDate += "0" + Month + "-";
				   }
				   if (Day >= 10 ){
				    CurrentDate += Day + " ";
				   }else{
				    CurrentDate += "0" + Day ;
				   }
				   
				   if (Hour >= 10 ){
				    CurrentDate += Hour + ":";
				   }else{
				    CurrentDate += "0" + Hour + ":";
				   }
				   if (Minute >= 10 ){
				    CurrentDate += Minute + ":";
				   }else{
				    CurrentDate += "0" + Minute + ":" ;
				   }
				   if (Second >= 10 ){
				    CurrentDate += Second ;
				   }else{
				    CurrentDate += "0" + Second ;
				   }
				   return CurrentDate;
				}
		</script>
	</head>
	<body>
		<input name="callerId" type="hidden"/>
		<div class="lt">
			<!--头部-->
			<div class="lt_top"><img src="images/zx_01.jpg" class="l"><span>欢迎您的来访</span><img src="images/zx_05.jpg" class="r"></div>
		    <!--头部  结束-->
		    <!--信息展示-->
		  <div class="lt_main">
		        <textarea name="show_message" class="text" readonly="readonly"></textarea>
		        <div class="kz"><img src="images/zx_14.jpg"></div>
		    </div>
		    <!--信息展示  结束-->
		    <!--消息发送-->
		    <div class="lt_xx">
		    	<img src="images/zx_09.jpg" class="l">
		    	<textarea name="send_message"></textarea>
		    	<img src="images/zx_20.jpg" class="an" οnclick="sendMessage()">
		    </div>
		    <!--消息发送  结束-->
		    <div class="lt_right">
		    	<img src="images/zx_06.jpg" class="t">
		        <img src="images/zx_26.jpg" width="125" height="184" class="tu">
		        <img src="images/zx_22.jpg" class="b">
		    </div>
		</div>
	</body>
</html>


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值