Comet反向ajax技术实现客服聊天系统

说明:Comet反向Ajax是在看了燕十八老师的视频以后,结合他讲解的例子,自己用ajax+java实现了一遍。在这里把代码贴出来,以供大家学习。同时,ajax轮询技术也可以用在消息推送的功能中,下次有时间,可以把相关的代码和设计思路贴出来,一起学习学习!

客户端代码:

 <!DOCTYPE html>
<html>
<head>
<title>客户端</title> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style>
*{margin:0; padding:0;}
h1{padding-left:300px;}
#msg{margin:20px;width:800px;height:400px;background:#ccc;border:2px solid #000;padding-left:10px;font-family: "微软雅黑";
font-size: 14px;padding:20px;overflow:auto;}
#msg p{line-height:20px;}
.say p:nth-of-type(2){text-indent: 20px;}
.reply{text-align:right;color:blue;}
#operate{margin:20px;font-family: "微软雅黑";font-size:14px;}
#operate #content{width:600px;height:30px;padding-left:10px;}
#operate input:nth-of-type(2){width:80px;height:30px;font-family: "微软雅黑";}
</style>
</head> <body>
<h1>客户端发送信息</h1>
<div id="msg">
</div>
<div id="operate">
<input type="text" id="content" placeholder="请输入发送内容"/>
<input type="button" value="点击发送" onclick="sendHandler();">
</div>
</body>
</html>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
window.onload = function(){
function autoSend(){
xhr.open("POST", "getClientMsg.do",true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText != "reload")setValue(xhr.responseText);
window.setTimeout(function(){
autoSend();
}, 500);
}
};
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
}
autoSend();
} function setValue(result){
console.log("result",result);
var strs = result.split("&");
var date = new Date();
date = date.toLocaleDateString();
document.getElementById("msg").innerHTML += "<div class='say'><p>客服中心&nbsp;"+date+"</p><p>"+strs[1]+"</p></div>";
}
//发送数据
function sendHandler(){
var oContent = document.getElementById("content");
if(null != oContent.value){
var xhr = new XMLHttpRequest();
xhr.open("POST", "sendMsg.do",true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText == "success"){
var date = new Date();
date = date.toLocaleDateString();
document.getElementById("msg").innerHTML += "<div class='reply'><p>我&nbsp;"+date+"</p>"+
"<p>"+oContent.value+"</p></div>";
document.getElementById("content").value = "";
}
}
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("sendIdentity=client&content="+oContent.value); }
} </script>

客户端获取消息代码:

package com.sgepit.ajax;

import java.io.IOException;
import java.sql.Connection; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.sgepit.ajax.entity.Msg;
import com.sgepit.ajax.util.DBCon; /**
* @author tengri
* @since 2015-12-12 下午9:59:45
* @description: 客户端获取消息
*/
@SuppressWarnings("all")
@WebServlet("/getClientMsg.do")
public class GetClientMsg extends HttpServlet { @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
try {
Connection conn = DBCon.getConnection();
QueryRunner qr = new QueryRunner();
String clientIP = req.getRemoteAddr();
String sql = "select * from msg where rec =? and isread = 0 limit 1";
Object[] param = {clientIP};
Msg msg = null;
resp.setCharacterEncoding("utf-8");
long startTime = System.currentTimeMillis();
while(true){
msg = qr.query(DBCon.getConnection(), sql, new BeanHandler(Msg.class), param);
if(null != msg ){
String result = msg.getPos() + "&" + msg.getContent();
System.out.println("clientMsg:" + result);
resp.getWriter().write(result);
sql = "update msg set isread=1 where uuid=?";
Object[] param2 = {msg.getUuid()};
qr.update(conn, sql, param2);
break;
}
if(System.currentTimeMillis() - startTime >=5000){
resp.getWriter().write("reload");
break;
}
Thread.sleep(500);
}
} catch (Exception e) {
resp.getWriter().write("error");
}
}
}

  客服端:

 <!DOCTYPE html>
<html>
<head>
<title>客服端</title>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<style>
*{margin:0; padding:0;}
h1{padding-left:300px;}
#msg{margin:20px;width:800px;height:400px;background:#ccc;border:2px solid #000;padding-left:10px;font-family: "微软雅黑";
font-size: 14px;padding:20px;overflow:auto;}
#msg p{line-height:20px;}
.say p:nth-of-type(1){cursor: pointer;}
.say p:nth-of-type(2){text-indent: 20px;}
.reply{text-align:right;color:blue;}
#operate{margin:20px;font-family: "微软雅黑";font-size:14px;}
#operate #content{width:600px;height:30px;padding-left:10px;}
#operate input:nth-of-type(2){width:80px;height:30px;font-family: "微软雅黑";}
</style>
</head> <body>
<h1>服务端回复信息</h1>
<div id="msg">
</div>
<div id="operate">
<p>回复人:<span id="person"></span></p><br/>
<input type="text" id="content" placeholder="请输入回复内容"/>
<input type="button" value="点击回复" onclick="replyHandler();">
</div>
</body>
</html>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
window.onload = function(){
document.getElementById("msg").onclick = function(ev){
var event = ev || window.event;
if(event.target.nodeName.toLowerCase() == "span"){
document.getElementById("person").innerHTML = event.target.innerText;
}
} function autoSend(){
xhr.open("POST", "getServerMsg.do",true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText != "reload")setValue(xhr.responseText);
window.setTimeout(function(){
autoSend();
}, 500);
}
};
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(null);
}
autoSend();
}
function setValue(result){
var strs = result.split("&");
var date = new Date();
date = date.toLocaleDateString();
document.getElementById("msg").innerHTML += "<div class='say'><p class='clientIp'>"+
"<span>"+strs[0]+"</span>&nbsp;"+date+"</p><p>"+strs[1]+"</p></div>";
}
//发送回复内容
function replyHandler(){
var value = document.getElementById("content").value;
var rec = document.getElementById("person").innerText;
if(!rec){
alert("请选择回复人");
return;
}
if(null != value){
var xhr = new XMLHttpRequest();
xhr.open("POST", "sendMsg.do",true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
if(xhr.responseText == "success"){
var date = new Date();
date = date.toLocaleDateString();
document.getElementById("msg").innerHTML += "<div class='reply'><p>我&nbsp;"+date+"</p><p>"+value+"</p></div>";
document.getElementById("content").value = "";
}
}
}
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("sendIdentity=admin&content="+value+"&rec="+rec);
}
}
</script>

  服务端获取消息代码:

 package com.sgepit.ajax;

 import java.io.IOException;
import java.sql.Connection; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.sgepit.ajax.entity.Msg;
import com.sgepit.ajax.util.DBCon; /**
* @author tengri
* @since 2015-12-12 下午9:59:45
* @description: 服务端获取消息
*/
@SuppressWarnings("all")
@WebServlet("/getServerMsg.do")
public class GetServerMsg extends HttpServlet { @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
try {
Connection conn = DBCon.getConnection();
QueryRunner qr = new QueryRunner();
String clientIP = req.getRemoteAddr();
String sql = "select * from msg where rec =? and isread = 0 limit 1";
Object[] param = {"admin"};
Msg msg = null;
resp.setCharacterEncoding("utf-8"); //处理中文乱码
long startTime = System.currentTimeMillis();
while(true){
msg = qr.query(DBCon.getConnection(), sql, new BeanHandler(Msg.class), param);
if(null != msg ){
String result = msg.getPos() + "&" + msg.getContent();
System.out.println("servler:" +result);
resp.getWriter().write(result);
sql = "update msg set isread=1 where uuid=?";
Object[] param2 = {msg.getUuid()};
qr.update(conn, sql, param2);
break;
}
if(System.currentTimeMillis() - startTime >=5000){
resp.getWriter().write("reload");
break;
}
Thread.sleep(500);
}
} catch (Exception e) {
e.printStackTrace();
resp.getWriter().write("error");
}
}
}

  发送消息代码:客户端和客服端发送消息都是调用同一个接口,只是在后台做了相关判断。

 package com.sgepit.ajax;

 import java.io.IOException;

 import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler; import com.sgepit.ajax.entity.Msg;
import com.sgepit.ajax.util.DBCon; /**
* @author tengri
* @since 2015-12-12 下午9:59:24
* @description: 发送消息
*/
@SuppressWarnings("all")
@WebServlet("/sendMsg.do")
public class SendMsg extends HttpServlet { @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String sendIdentity = req.getParameter("sendIdentity");
String content = req.getParameter("content");
String rec = "admin";
String pos = "admin";
try {
//如果是服务端发送消息,则会传过来接收者对象,如果是客户端发送消息,接收者为admin,发送端为当前ip用户
if("admin".equals(sendIdentity)){
rec = req.getParameter("rec");
}else{
pos = req.getRemoteAddr();
}
QueryRunner qr = new QueryRunner();
String sql = "insert into msg(rec,pos,content,isread)values(?,?,?,0)";
Object[] params = {rec,pos,content};
qr.insert(DBCon.getConnection(),sql, new BeanHandler(Msg.class), params);
resp.getWriter().write("success");
} catch (Exception e) {
resp.getWriter().write("error");
e.printStackTrace();
}
}
}

  截图:

Comet反向ajax技术实现客服聊天系统

Comet反向ajax技术实现客服聊天系统

上一篇:(五)HttpClient 连接超时及读取超时


下一篇:用R语言分析我的fitbit计步数据