html5客服系统源码(客服系统源码)

   2023-04-25 互联网0
核心提示:h5效果图 h5页面聊天 vue效果图 vue页面聊天 功能实现 spring boot + webSocket 实现 官方地址 https://docs.spring.io/spring-framework/docs/5.0
h5效果图

h5页面聊天

vue效果图

vue页面聊天

功能实现 spring boot + webSocket 实现 官方地址 https://docs.spring.io/spring-framework/docs/5.0.8.RELEASE/spring-framework-reference/web.html#websocket

maven 配置文件

org.springframework.boot spring-boot-starter-thymeleaf com.alibaba fastjson 1.2.78 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-websocket org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test

webSocket 配置

package com.example.webchat.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "myHandler/") // 访问路径 .addInterceptors(new WebSocketHandlerInterceptor()) // 配置拦截器 .setAllowedOrigins("*"); // 跨域 } @Bean public ServletServerContainerFactoryBean createWebSocketContainer() { ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); container.setMaxTextMessageBufferSize(8192); // 例如消息缓冲区大小、空闲超时等 container.setMaxBinaryMessageBufferSize(8192); return container; } @Bean public WebSocketHandler myHandler() { return new MyHandler(); }}

消息处理类

package com.example.webchat.config;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.example.webchat.pojo.DataVo;import org.springframework.web.socket.CloseStatus;import org.springframework.web.socket.TextMessage;import org.springframework.web.socket.WebSocketSession;import org.springframework.web.socket.handler.AbstractWebSocketHandler;import java.io.IOException;import java.util.*;import java.util.concurrent.ConcurrentHashMap;public class MyHandler extends AbstractWebSocketHandler { private static int onlineCount = 0; // 线程安全 private static Map userMap = new ConcurrentHashMap<>(); // 用户 private static Map adminMap = new ConcurrentHashMap<>(); // 客服 @Override public void afterConnectionEstablished(WebSocketSession session) throws IOException { addonlineCount(); // 当前用户加 1 System.out.println(session.getId()); Map map = session.getAttributes(); Object token = map.get("token"); Object admin = map.get("admin"); DataVo dataVo = new DataVo(); dataVo.setCode(9001).setMsg("连接成功"); if (Objects.nonNull(admin)) { adminMap.put(session.getId(), session); // 添加客服 } else { // 分配客服 userMap.put(session.getId(), session); // 添加当前用户 distribution(dataVo); } dataVo.setId(session.getId()); System.out.println("用户连接成功:" + admin); System.out.println("用户连接成功:" + token); System.out.println("在线用户:" + getonlineCount()); this.sendMsg(session, JSONObject.toJSonString(dataVo)); } private void distribution(DataVo vo) { if (adminMap.size() != 0) { Random random = new Random(); int x = random.nextInt(adminMap.size()); Set values = adminMap.keySet(); int j = 0; for (String str : values) { if (j == x) { vo.setRecId(str); System.out.println("分配ID:" + str); break; } j++; } } } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { System.out.print("用户ID:" + session.getId()); String payload = message.getPayload(); System.out.println("接受到的数据:" + payload); DataVo dataVo = JSON.toJavaObject(JSON.parseObject(payload), DataVo.class); // json 转对象 if (Objects.isNull(dataVo.getRecId()) || dataVo.getRecId().equals("")) { // 用户客服为空 分配客服 WebSocketSession socketSession = adminMap.get(session.getId()); if (Objects.isNull(socketSession)) { this.distribution(dataVo); } } if (dataVo.getCode() == 9002) { if (Objects.nonNull(dataVo.getRecId())) { // user -> admin WebSocketSession socketSession = adminMap.get(dataVo.getRecId()); dataVo.setSelfId(session.getId()).setRecId(""); this.sendMsg(socketSession, JSONObject.toJSonString(dataVo)); } else if (Objects.nonNull(dataVo.getSelfId())) { // admin ->user WebSocketSession socketSession = userMap.get(dataVo.getSelfId()); dataVo.setRecId(session.getId()).setSelfId(""); this.sendMsg(socketSession, JSONObject.toJSonString(dataVo)); } } } private void sendMsg(WebSocketSession session, String msg) throws IOException { session.sendMessage(new TextMessage(msg)); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { subonlineCount(); // 当前用户加 1 adminMap.remove(session.getId()); userMap.remove(session.getId()); System.out.println("用户断开连接token:" + session.getId()); System.out.println("用户断开连接admin:" + session.getId()); System.out.println("在线用户:" + getonlineCount()); } public static synchronized int getonlineCount() { return onlineCount; } public static synchronized void addonlineCount() { MyHandler.onlineCount++; } public static synchronized void subonlineCount() { MyHandler.onlineCount--; }}

配置拦截器

package com.example.webchat.config;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;import javax.servlet.http.HttpServletRequest;import java.util.Map;import java.util.Objects;public class WebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) throws Exception { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpServletRequest re = servletRequest.getServletRequest(); Object token = re.getParameter("token"); Object admin = re.getParameter("admin"); if (Objects.isNull(token)) { return false; } re.getSession().setAttribute("admin", admin); re.getSession().setAttribute("token", token); return super.beforeHandshake(request, response, wsHandler, attributes); } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { super.afterHandshake(request, response, wsHandler, ex); }}

h5服务端

ta charset="utf-8">服务端

服务端发送消息

ntenteditable=truestyle="width: 500px;height: 500px;margin: 0px auto;border: 1px solid #000000;padding: 10px;border-radius: 10px;overflow: auto;">
cript src="http://code.jquery.com/jquery-2.1.1.min.js">cript>cript type="text/javascript">$(() => {var pushData = {code: 9002,msg: \'\',selfId: \'\',};var time = null;var path = \'ws://127.0.0.1:8009/myHandler/\';if (typeof(WebSocket) === "undefined") {alert(\'不支持websocket\')return;}let id = Math.random(); // 随机数// 实例化socketvar webSocket = new WebSocket(path + \'?token=\' + id+\'&admin=1\');// 监听连接webSocket.onopen = function(event) {console.log(event);interval();};// 监听消息webSocket.onmessage = function(event) {let data = JSON.parse(event.data); pushData.selfId = data.selfId;if (data.code == 9002) {$(\'#content\').append(`

${data.msg}:客户端

`)} else if (data.code == 9001) {$(\'#content\').append(`

连接成功

`);}console.log(event)};// 监听错误webSocket.onerror = function(event) {console.log(event)$(\'#content\').append(`

连接错误

`);clearInterval();};// 发送消息$(\'#button\').click(() => {let v = $(\'input\').val();if (v) {pushData.code = 9002;pushData.msg = v;webSocket.send(JSON.stringify(pushData));$(\'#content\').append(`

服务端:${v}

`)$(\'input\').val(\'\');}})function interval() {time = setInterval(() => {pushData.code = 9003;pushData.msg = \'心跳\';webSocket.send(JSON.stringify(pushData));}, 5000);}function clearInterval() {clearInterval(time);}})
cript>

客户端

ta charset="utf-8">客户端

客户端发送消息

ntenteditable=truestyle="width: 500px;height: 500px;margin: 0px auto;border: 1px solid #000000;padding: 10px;border-radius: 10px;overflow: auto;">
cript src="http://code.jquery.com/jquery-2.1.1.min.js">cript>cript type="text/javascript">$(() => {var pushData = {code: 9002,msg: \'\',recId: \'\',};var time = null;var path = \'ws://127.0.0.1:8009/myHandler/\';if (typeof(WebSocket) === "undefined") {alert(\'不支持websocket\')return;}let id = Math.random(); // 随机数// 实例化socketvar webSocket = new WebSocket(path + \'?token=\' + id);// 监听连接webSocket.onopen = function(event) {console.log(event);interval();};// 监听消息webSocket.onmessage = function(event) {let data = JSON.parse(event.data);if (data.code == 9002) {$(\'#content\').append(`

${data.msg}:服务端

`)} else if (data.code == 9001) {$(\'#content\').append(`

连接成功

`);}console.log(event)};// 监听错误webSocket.onerror = function(event) {console.log(event)$(\'#content\').append(`

连接错误

`);clearInterval();};// 发送消息$(\'#button\').click(() => {let v = $(\'input\').val();if (v) {pushData.code = 9002;pushData.msg = v;webSocket.send(JSON.stringify(pushData));$(\'#content\').append(`

客户端:${v}

`)$(\'input\').val(\'\');}})function interval() {time = setInterval(() => {pushData.code = 9003;pushData.msg = \'心跳\';webSocket.send(JSON.stringify(pushData));}, 5000);}function clearInterval() {clearInterval(time);}})
cript>
 
标签: 源码 系统 用户
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与爱美生活网(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • 怎么获取小程序的源码
    怎么获取小程序的源码
    获取小程序的源码要打开安卓模拟器,并在模拟器中安装QQ、微信、RE管理器,然后在模拟器里打开微信,运行你想要获取的小程序,在模拟器运行后,直接切回模拟器桌面运行RE浏览器,来到目录,里面的.wxapkg后缀的文件就是源码。.wxapkg是一
  • DZ论坛如何安装
    DZ论坛如何安装
    DZ论坛的安装很多朋友指导如何去安装!下面给大家讲解一下工具/原料空间FTP工具网站的源码方法/步骤1首先将下载下来的DZ源码解压出来获得源码其中有UPLODA2然后将你的ftp连接上确定您的空间为PHP版本,然后用FTP将网站的源码上传到
  • 小程序源码怎么用(即可程序是一种项)
    小程序源码怎么用(即可程序是一种项)
    小程序源码可通过填写AppID,项目名称,选择本地开发目录,点击添加项目来使用。小程序,是一种不需要下载安装即可使用的应用,它实现了应用触手可及的梦想,用户扫一扫或搜一下即可打开应用。
点击排行