首页 > 代码库 > webSocket客服在线交谈

webSocket客服在线交谈

一》用户端

<%@ page language="java" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>客户端</title>
<link rel="stylesheet" type="text/css" href="http://www.mamicode.com/${BasePath }/css/web/chatClt.css" />
<script type="text/javascript" src="http://www.mamicode.com/${BasePath }/js/jquery-3.2.0.min.js"></script>
<script type="text/javascript" src="http://www.mamicode.com/${BasePath }/js/web/chatClt.js"></script>
</head>
<body class="keBody">
<div class="kePublic">
<!--效果html开始-->
    <div class="content">
        <div class="chatBox">
            <div class="chatLeft">
                <div class="chat01">
                    <div class="chat01_title">
                        <ul class="talkTo">
                            <li><a href="javascript:;">游客</a></li></ul>
                    </div>
                    <div class="chat01_content">
                        <div class="message_box mes3" style="display: block;">
                        <!-- 聊天记录开始 -->
                        <c:forEach  items="${chat}"  var="ch">
                        <!--主动发信人 客户  -->
                          <c:if  test="${ch.send_type==1}">
                            <div class=‘message clearfix‘ >
                                <div class=‘user-logo‘>
                                    <img  width=‘45px‘ src="http://www.mamicode.com/${BasePath}/images/ico1.jpg"/>
                                </div>
                                <div class=‘wrap-text‘>
                                    <h5 class=‘clearfix‘>游客</h5>
                                    <div>${ch.chat_content}</div>
                                </div>
                                <div class=‘wrap-ri‘>
                                    <div clsss=‘clearfix‘><span>
                        <fmt:parseDate  value="http://www.mamicode.com/${ch.send_time}"  var="time"></fmt:parseDate>
                                <fmt:formatDate value="http://www.mamicode.com/${time}"  pattern="yyyy-MM-dd HH:mm:ss"/>
                                   </span></div>
                                </div>
                                <div style=‘clear:both;‘></div></div><div style=‘clear:both;‘></div>
                          </c:if>
                         <!--主动发信人 客服  -->
                          <c:if  test="${ch.send_type==2}">
                                <div class=‘messages clearfix‘ >
                                    <div  class=‘user-logo‘>
                                        <img  width=‘45px‘ src=http://www.mamicode.com/‘${BasePath}/images/svr.gif‘/>
                                    </div>
                                    <div class=‘wrap-text‘>
                                            <h5 class=‘clearfix‘>客服</h5>
                                    <div>${ch.chat_content}</div>
                                        </div>
                                        <div class=‘wrap-ri‘>
                                        <div clsss=‘clearfix‘>
                                        <span>
                                <fmt:parseDate  value="http://www.mamicode.com/${ch.send_time}"  var="time"></fmt:parseDate>
                                <fmt:formatDate value="http://www.mamicode.com/${time}"  pattern="yyyy-MM-dd HH:mm:ss"/></span>
                                    </div>
                                    </div>
                                <div style=‘clear:both;‘></div></div><div style=‘clear:both;‘></div>
                          </c:if>
                        </c:forEach>
                        <!-- 聊天记录结束 -->
                         </div>
                    </div>
                </div>
                <div class="chat02">
                    <div class="chat02_title">
                        <a class="chat02_title_btn ctb01" href="javascript:;"></a>
                       <div style="float: right;position:relative;top:5px;">
                           <a class="" href="http://www.mamicode.com/${BasePath}/web/delCltrecord.do"  onclick="return confirm(‘确定要删除吗‘)">
                               <span style="color:#3A5FCD">删除聊天记录</span></a></div>
                        <div class="wl_faces_box">
                            <div class="wl_faces_content">
                                <div class="title">
                                    <ul>
                                        <li class="title_name">常用表情</li>
                                        <li class="wl_faces_close"><span>&nbsp;</span></li>
                                      </ul>
                                </div>
                                <div class="wl_faces_main">
                                    <jsp:include page="/include/webSocket/img.jsp"></jsp:include>
                                </div>
                            </div>
                            <div class="wlf_icon">
                            </div>
                        </div>
                    </div>
                    <div class="chat02_content">
                        <textarea id="textarea" ></textarea>
                    </div>
                    <div class="chat02_bar">
                        <ul>
                               <li style="left: 20px; top: 10px; padding-left: 30px;">来源:
                                    <a href="http://www.internetke.com/" target="_blank" id="haha">宜家</a>
                               </li>
                               <li style="right: 5px; top: 5px;">
                                    <img src="http://www.mamicode.com/${BasePath }/images/img/send_btn.jpg">
                                </li>
                        </ul>
                    </div>
                </div>
            </div>
            <!-- 获取后台自己的uuid -->
            <input type="hidden" id="uuid" value="http://www.mamicode.com/${uuid }">
            <c:forEach  items="${webSet}" var ="w">
               <input type="hidden" id="svrUuid" value="http://www.mamicode.com/${w.uuid}">
               </c:forEach>
            <div style="clear:both;"> </div>
        </div>
    </div>
<!--效果html结束-->
</div>
<script type="text/javascript">

var websocket = null;
//判断当前浏览器是否支持WebSocket
if (‘WebSocket‘ in window) {
    var uuid="${uuid}";
    websocket = new WebSocket("ws://192.168.6.26:8080/family/websocket?clt"+uuid );
} else {
    alert(‘当前浏览器 Not support websocket‘)
}

//连接发生错误的回调方法
websocket.onerror = function() {
    setMessageInnerHTML("WebSocket连接发生错误");
};

//连接成功建立的回调方法
websocket.onopen = function() {
    setMessageInnerHTML("WebSocket连接成功");
}

//接收到消息的回调方法
websocket.onmessage = function(event) {
    //setMessageInnerHTML(event.data);
    var e=new Date,f="";
    f+=e.getFullYear()+"-",
    f+=e.getMonth()+1+"-",
    f+=e.getDate()+"  ",
    f+=e.getHours()+":",
    f+=e.getMinutes()+":",
    f+=e.getSeconds();
    //接收到的信息
    var mess=event.data;
    //信息要发送的uuid
    var uuids=mess.substring(mess.length-36,mess.length);
 //接收到的信息 真正要发送的内容
    var sendmsg=mess.substring(36,mess.length-36);
    var sssss="<div class=‘messages clearfix‘ ><div  class=‘user-logo‘><img  width=‘45px‘ src=http://www.mamicode.com/‘/family/images/svr.gif‘/>

客服
"+sendmsg+"</div></div><div class=‘wrap-ri‘><div clsss=‘clearfix‘><span>"+f+"</span></div></div><div style=‘clear:both;‘></div></div><div style=‘clear:both;‘></div>";
    $(".mes3").append(sssss);
}

////连接关闭的回调方法
websocket.onclose = function() {
    setMessageInnerHTML("WebSocket连接关闭");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
    closeWebSocket();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
    document.getElementById(‘haha‘).innerHTML +=innerHTML + ‘<br/>‘;
}


// 关闭WebSocket连接
function closeWebSocket() {
    websocket.close();
}
//发送消息
function send() {
    var message = document.getElementById(‘textarea‘).value;
    websocket.send("clt"+message);
}


//刷新上线人信息
function showLst(){
    var url="${BasePath}/web/cltAjax.do";
    $.post(url,function(str){
        var strs=eval(str);
        var lili="";
        $("#ulul").html("");
        for (var i= 0; i <strs.length; i++) {
            lili+="<li><label ><input type=‘radio‘ name=‘xuanzhong‘ value=http://www.mamicode.com/‘"+strs[i].uuid+"‘> "+strs[i].uuid+"</label>";
        }
        $("#ulul").html(lili);
    });
}
//setInterval("showLst()",10000);
</script>
</body>
</html>

二》客服端

<%@ page language="java" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>服务端</title>
<script type="text/javascript" src="http://www.mamicode.com/${BasePath }/js/jquery-3.2.0.min.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.mamicode.com/${BasePath }/css/web/chatsvr.css" />
<script type="text/javascript" src="http://www.mamicode.com/${BasePath }/js/web/chatsvr.js"></script>
</head>
<body class="keBody frameBody">
<div class="kePublic">
<!--效果html开始-->
<!-- 获取后台传来的自己的uuid -->
  <input type="hidden" id="uuid" value="http://www.mamicode.com/${uuid }">
    <div class="content">
        <div class="chatBox">
            <div class="chatLeft">
            
                <div class="chat01">
                    <div class="chat01_title">
                        <ul class="talkTo">
                            <li><a href="javascript:;">王旭</a></li></ul>
                                   <a class="close_btn" href="javascript:;"></a>
                    </div>
                    <div class="chat01_content">
                        <div class="message_box mes3" style="display: block;"> </div>
                    </div>
                </div>
                
                <div class="chat02">
                    <div class="chat02_title">
                        <a class="chat02_title_btn ctb01" href="javascript:;"></a>
                        
                        <div class="wl_faces_box">
                            <div class="wl_faces_content">
                                <div class="title">
                                    <ul>
                                        <li class="title_name">常用表情</li><li class="wl_faces_close"><span>&nbsp;</span></li></ul>
                                </div>
                                <div class="wl_faces_main">
                                    <jsp:include page="/include/webSocket/img.jsp"></jsp:include>
                                </div>
                            </div>
                            <div class="wlf_icon">
                            </div>
                        </div>
                    </div>
                    <div class="chat02_content">
                        <textarea id="textarea"></textarea>
                    </div>
                    <div class="chat02_bar">
                        <ul>
                            <li style="left: 20px; top:10px; padding-left: 30px;">来源:
                            <a href="http://www.internetke.com/" target="_blank" id="haha">宜家</a></li>
                            <li style="right: 5px; top: 5px;">  
                              <img src="http://www.mamicode.com/${BasePath }/images/img/send_btn.jpg"></li>
                        </ul>
                    </div>
                </div>
            </div>
            <div class="chatRight">
                <div class="chat03">
                    <div class="chat03_title">
                        <label class="chat03_title_t"> 成员列表</label>
                    </div>
                    <div class="chat03_content">
                        <ul  id="ulul">
                             <c:forEach  items="${webSet}" var="w">
                                <li>
                                   <label ><input type="radio" name="xuanzhong" value="http://www.mamicode.com/${w.uuid}">${w.uuid}</label>
                                </li>
                              </c:forEach>
                        </ul>
                    </div>
                </div>
            </div>
            <div style="clear:both;"> </div>
        </div>
    </div>
<!--效果html结束-->
</div>
</body>
<<script type="text/javascript">
var websocket = null;
//判断当前浏览器是否支持WebSocket
if (‘WebSocket‘ in window) {
    var uuid="${uuid}";
    var url="ws://192.168.6.26:8080/family/websocket?svr"+uuid;
        websocket = new WebSocket(url);
} else {
    alert(‘当前浏览器 Not support websocket‘)
}

//连接发生错误的回调方法
websocket.onerror = function() {
    setMessageInnerHTML("WebSocket连接发生错误");
};

//连接成功建立的回调方法
websocket.onopen = function() {
    setMessageInnerHTML("WebSocket连接成功");
}

//接收到消息的回调方法
websocket.onmessage = function(event) {
    //setMessageInnerHTML(event.data);
    var e=new Date,f="";
    f+=e.getFullYear()+"-",
    f+=e.getMonth()+1+"-",
    f+=e.getDate()+"  ",
    f+=e.getHours()+":",
    f+=e.getMinutes()+":",
    f+=e.getSeconds();
    var mess=event.data;
    var uuids=mess.substring(mess.length-36,mess.length);
 var sendmsg=mess.substring(0,mess.length-36);
    var sssss="<div class=‘messages clearfix‘ ><div class=‘user-logo‘><img width=‘45px‘  src=http://www.mamicode.com/‘/family/images/ico1.jpg‘/>

游客
"+event.data+"</div></div><div class=‘wrap-ri‘><div clsss=‘clearfix‘><span>"+f+"</span></div></div><div style=‘clear:both;‘></div></div><div style=‘clear:both;‘></div>";
    $(".mes3").append(sssss);
}

////连接关闭的回调方法
websocket.onclose = function() {
    setMessageInnerHTML("WebSocket连接关闭");
}

//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function() {
    closeWebSocket();
}

//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
    document.getElementById(‘haha‘).innerHTML +=innerHTML + ‘<br/>‘;
}


// 关闭WebSocket连接
function closeWebSocket() {
    websocket.close();
}
//发送消息
function send() {
    var message = document.getElementById(‘textarea‘).value;
    websocket.send("svr"+message);
}


/**
 * 刷新在线人数
 */
function showLst(){
    var url="${BasePath}/web/svrAjax.do";
    $.post(url,function(str){
        var strs=eval(str);
        var lili="";
        $("#ulul").html("");
        for (var i= 0; i <strs.length; i++) {
            lili+="<li><label ><input type=‘radio‘ name=‘xuanzhong‘ value=http://www.mamicode.com/‘"+strs[i].uuid+"‘> "+strs[i].uuid+"</label></li>";
        }
        $("#ulul").html(lili);
    });
}
//setInterval("showLst()",10000);
</script>
</html>

三》服务器端

package com.wskj.app.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 */
@ServerEndpoint("/websocket")
public class WebSocketTest {
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static List<WebSocketTest> cltSet = new ArrayList<WebSocketTest>();
    private static List<WebSocketTest> svrSet = new ArrayList<WebSocketTest>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    //客户还是服务人员
    private String type;
    //昵称
    private String nickName;
    private String uuid;
    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session){
        
        ///获取前台的url
        String url=session.getRequestURI().toString();
        //获取url字符串最后三位
        String types=url.substring(url.length()-39, url.length()-36);
        this.uuid=url.substring(url.length()-36, url.length());
        this.type=types;
        this.session = session;
        //如果前台传来的是客户 存入 cltSet  
        //服务端 存入 svr
        if(types.equals("svr")){
            svrSet.add(this);     //加入set中
        }else if(types.equals("clt")){
            cltSet.add(this);     //加入set中
        }
        
        addOnlineCount();           //在线数加1
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()+"\n"+getUuid());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(){
        cltSet.remove(this);  //从set中删除
        svrSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage (String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
        //群发消息
        String types=message.substring(36,39);
        //发信人的uuid
        String uuids=message.substring(0,36);
        //接信人的uuid
        String beiUuids=message.substring(message.length()-36,message.length());
        if(types.equals("clt")){
            for(WebSocketTest itemSvr: svrSet){
                if(itemSvr!=null && itemSvr.uuid.equals(beiUuids)){
                    try {
                        itemSvr.sendMessage(message.substring(3,message.length()-36)+uuids);
                        System.out.println(message.substring(3,message.length()-36)+uuids);
                    } catch (IOException e) {
                        e.printStackTrace();
                        continue;
                    }
                }
            }
            
        }
       //如果传过来的是服务人员  根据选择的uuid 发送消息        
        if(types.equals("svr")){
            for(WebSocketTest itemClt: cltSet){
                if(itemClt!=null && itemClt.uuid.equals(beiUuids)){
                    try {
                        itemClt.sendMessage(message.substring(3,message.length()-36)+uuids);
                        System.out.println(message.substring(3,message.length()-36)+uuids);
                    } catch (IOException e) {
                        e.printStackTrace();
                        continue;
                    }
                }
            }
            
        }
    }

    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void one rror(Session session, Throwable error){
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketTest.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketTest.onlineCount--;
    }

    

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public static void setOnlineCount(int onlineCount) {
        WebSocketTest.onlineCount = onlineCount;
    }

    public static List<WebSocketTest> getCltSet() {
        return cltSet;
    }

    public static void setCltSet(List<WebSocketTest> cltSet) {
        WebSocketTest.cltSet = cltSet;
    }

    public static List<WebSocketTest> getSvrSet() {
        return svrSet;
    }

    public static void setSvrSet(List<WebSocketTest> svrSet) {
        WebSocketTest.svrSet = svrSet;
    }

}

四》pojo 文件

package com.wskj.app.pojo;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint("/svr1")
public class WebSocket {
    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    private static Set<WebSocket> socket = new HashSet<WebSocket>();
    private Session session;
    private String name;

    /**
     * 连接建立成功调用的方法
     *
     * @param session
     *            可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        socket.add(this); // 加入set中
        onlineCount++; // 在线数加1
        System.out.println("有新连接加入!当前在线人数为" + onlineCount);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        socket.remove(this); // 从set中删除
        onlineCount--; // 在线数减1
        System.out.println("有一连接关闭!当前在线人数为" + onlineCount);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     *            客户端发送过来的消息
     * @param session
     *            可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);
        // 群发消息
        for (WebSocket item : socket) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }
    }
       /**
      * 发生错误时调用
          * @param session
         * @param error
          */
        @OnError
        public void one rror(Session session,Throwable error){
            System.out.println("发生错误");
             error.printStackTrace();
         }
    
    public void sendMessage(String message) throws IOException{
                this.session.getBasicRemote().sendText(message);
           //this.session.getAsyncRemote().sendText(message);
         }
    /*
     * @OnMessage public void onMessage(String message, Session session) throws
     * IOException, InterruptedException {
     *
     * // 打印出来客户端发来的消息 System.out.println("Received: " + message);
     *
     * // Send the first message to the client
     * session.getAsyncRemote().sendText("这是第一条服务器端的消息");
     *
     *
     * // Send 3 messages to the client every 5 seconds int sentMessages = 0;
     * while(sentMessages < 3){ Thread.sleep(5000);
     * session.getAsyncRemote().sendText("这是第二条服务器端的消息 "+sentMessages);
     * sentMessages++; }
     *
     * // Send a final message to the client
     * session.getAsyncRemote().sendText("这是最后一条服务器端的消息"); }
     */

}

webSocket客服在线交谈