牛逼,spring boot+vue實(shí)現(xiàn)H5聊天室客服功能 (附源碼)
h5效果圖

vue效果圖

功能實(shí)現(xiàn)
spring boot?+?webSocket?實(shí)現(xiàn)官方地址?https://docs.spring.io/spring-framework/docs/5.0.8.RELEASE/spring-framework-reference/web.html#websocket
maven 配置文件
"1.0"?encoding="UTF-8"?>
"http://maven.apache.org/POM/4.0.0"
?????????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?????????xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd">
????4.0.0
????
????????org.springframework.boot
????????spring-boot-dependencies
????????2.2.0.RELEASE
????
????org.example
????webChat
????1.0-SNAPSHOT
????
????????1.8
????
????
????????
????????????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
????????
????
????
????????
????????????
????????????????org.springframework.boot
????????????????spring-boot-maven-plugin
????????????????
????????????????????
????????????????????????
????????????????????????????org.projectlombok
????????????????????????????lombok
????????????????????????
????????????????????
????????????????
????????????
????????
????
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;
/**
?*?@author?Mr.Fang
?*?@title:?WebSocketConfig
?*?@Description:?web?socket?配置
?*?@date?2021/11/14?13:12
?*/
@Configuration
@EnableWebSocket
public?class?WebSocketConfig?implements?WebSocketConfigurer?{
????@Override
????public?void?registerWebSocketHandlers(WebSocketHandlerRegistry?registry)?{
????????registry.addHandler(myHandler(),?"myHandler/")?//?訪問(wèn)路徑
????????????????.addInterceptors(new?WebSocketHandlerInterceptor())??//?配置攔截器
????????????????.setAllowedOrigins("*");?//?跨域
????}
????@Bean
????public?ServletServerContainerFactoryBean?createWebSocketContainer()?{
????????ServletServerContainerFactoryBean?container?=?new?ServletServerContainerFactoryBean();
????????container.setMaxTextMessageBufferSize(8192);??//?例如消息緩沖區(qū)大小、空閑超時(shí)等
????????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;
/**
?*?@author?Mr.Fang
?*?@title:?MyHandler
?*?@Description:?消息處理類
?*?@date?2021/11/14?13:12
?*/
public?class?MyHandler?extends?AbstractWebSocketHandler?{
????private?static?int?onlineCount?=?0;
????//????線程安全
????private?static?Map?userMap?=?new?ConcurrentHashMap<>();?//?用戶
????private?static?Map?adminMap?=?new?ConcurrentHashMap<>();?//?客服
????/**
?????*?@Description:?連接成功之后
?????*?@param?session
?????*?@return?void
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:15
?????*/
????@Override
????public?void?afterConnectionEstablished(WebSocketSession?session)?throws?IOException?{
????????addOnlineCount();?//?當(dāng)前用戶加?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);?//?添加當(dāng)前用戶
????????????distribution(dataVo);
????????}
????????dataVo.setId(session.getId());
????????System.out.println("用戶連接成功:"?+?admin);
????????System.out.println("用戶連接成功:"?+?token);
????????System.out.println("在線用戶:"?+?getOnlineCount());
????????this.sendMsg(session,?JSONObject.toJSONString(dataVo));
????}
????/**
?????*?@param?vo
?????*?@return?void
?????*?@Description:?分配客服
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:13
?????*/
????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++;
????????????}
????????}
????}
????/**
?????*?@param?session
?????*?@param?message
?????*?@return?void
?????*?@Description:?收發(fā)消息
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:13
?????*/
????@Override
????protected?void?handleTextMessage(WebSocketSession?session,?TextMessage?message)?throws?Exception?{
????????System.out.print("用戶ID:"?+?session.getId());
????????String?payload?=?message.getPayload();
????????System.out.println("接受到的數(shù)據(jù):"?+?payload);
????????DataVo?dataVo?=?JSON.toJavaObject(JSON.parseObject(payload),?DataVo.class);?//?json?轉(zhuǎn)對(duì)象
????????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));
????????????}
????????}
????}
????/**
?????*?@param?session
?????*?@param?msg
?????*?@return?void
?????*?@Description:?發(fā)送消息
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:14
?????*/
????private?void?sendMsg(WebSocketSession?session,?String?msg)?throws?IOException?{
????????session.sendMessage(new?TextMessage(msg));
????}
????/**
?????*?@Description:?斷開連接之后
?????*?@param?session
?????*?@param?status
?????*?@return?void
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:14
?????*/
????@Override
????public?void?afterConnectionClosed(WebSocketSession?session,?CloseStatus?status)?{
????????subOnlineCount();?//?當(dāng)前用戶加?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;
????}
????/**
?????*?@Description:?在線用戶?+1
?????*?@return?void
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:16
?????*/
????public?static?synchronized?void?addOnlineCount()?{
????????MyHandler.onlineCount++;
????}
????/**
?????*?@Description:?在線用戶?-1
?????*?@return?void
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:16
?????*/
????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;
/**
?*?@author?Mr.Fang
?*?@title:?WebSocketHandlerInterceptor
?*?@Description:?攔截器
?*?@date?2021/11/14?13:12
?*/
public?class?WebSocketHandlerInterceptor?extends?HttpSessionHandshakeInterceptor?{
????/**
?????*?@param?request
?????*?@param?response
?????*?@param?wsHandler
?????*?@param?attributes
?????*?@return?boolean
?????*?@Description:?握手之前
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:18
?????*/
????@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);
????}
????/**
?????*?@param?request
?????*?@param?response
?????*?@param?wsHandler
?????*?@param?ex
?????*?@return?boolean
?????*?@Description:?握手之后
?????*?@Author?Mr.Fang
?????*?@date?2021/11/14?13:18
?????*/
????@Override
????public?void?afterHandshake(ServerHttpRequest?request,?ServerHttpResponse?response,?WebSocketHandler?wsHandler,?Exception?ex)?{
????????super.afterHandshake(request,?response,?wsHandler,?ex);
????}
}
h5服務(wù)端
?
??"utf-8">
??服務(wù)端
??
?
?
??"client">
???"text-align:?center;">服務(wù)端發(fā)送消息
???"content"?contenteditable=true
????style="width:?500px;height:?500px;margin:?0px?auto;border:?1px?solid?#000000;padding:?10px;border-radius:?10px;overflow:?auto;">
???
???"padding:?5px;0px">
????type=""?value=""?/>?
???
??
??
??
?
客戶端
?
??"utf-8">
??客戶端
??
?
?
??"client">
???"text-align:?center;">客戶端發(fā)送消息
???"content"?contenteditable=true
????style="width:?500px;height:?500px;margin:?0px?auto;border:?1px?solid?#000000;padding:?10px;border-radius:?10px;overflow:?auto;">
???
???"padding:?5px;0px">
????type=""?value=""?/>?
???
??
??
??
?
vue?連接?webSocket
??"chat">
????"聊天內(nèi)容"?left-arrow?/>
????"content"?ref="rightBody">
??????"item?in?list"?:key="item.id">
????????"chat-model"?v-if="item.isSelf">
??????????
????????????"45px"?height="45px"?fit="fill"?round?src="https://img01.yzcdn.cn/vant/cat.jpeg"?/>
??????????
??????????"chat-content?chat-content-l">
????????????{{item.content}}
??????????
????????
????????"chat-model"?style="justify-content:?flex-end"?v-else>
??????????"chat-content?chat-content-r">
????????????{{item.content}}
??????????
??????????
????????????"45px"?height="45px"?fit="fill"?round?src="https://img01.yzcdn.cn/vant/cat.jpeg"?/>
??????????
????????
??????
????
????"bottom">
??????type="text"?v-model="text"?/>
??????"onSend">發(fā)送
????
??
源碼地址?
https://gitee.com/bxmms/web-chat.git
? 作者?|??天葬
來(lái)源 |??cnblogs.com/bxmm/p/15552285.html

評(píng)論
圖片
表情
