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 环境变量
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
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/\") // 浏览途径
.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;
/**
* @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<String, WebSocketSession> userMap = new ConcurrentHashMap<>(); // 客户
private static Map<String, WebSocketSession> 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(); // 现阶段客户加 1
System.out.println(session.getId());
Map<String, Object> 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));
}
/**
* @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<String> 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: 收取和发送信息
* @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(\"接纳到的数据信息:\" 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));
}
}
}
/**
* @param session
* @param msg
* @return void
* @Description: 推送信息
* @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(); // 现阶段用户加 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<String, Object> 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服务器端
<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\">
<title>服务端</title>
<style type=\"text/css\">
#client {
margin: 0px auto;
width: 500px;
}
input {
width: 80%;
height: 40px;
border-radius: 5px;
border-color: #CCCCCC;
outline: #01FA01;
}
#button {
width: 84px;
height: 46px;
background-color: #5af3a5;
color: #fff;
font-size: 20px;
border-radius: 5px;
border: none;
box-shadow: 1px 1px 1px 1px #ccc;
cursor: pointer;
outline: #01FA01;
}
</style>
</head>
<body>
<div id=\"client\">
<h1 style=\"text-align: center;\">服务器端推送信息</h1>
<div id=\"content\" contenteditable=true
style=\"width: 500px;height: 500px;margin: 0px auto;border: 1px solid #000000;padding: 10px;border-radius: 10px;overflow: auto;\">
</div>
<div style=\"padding: 5px;0px\">
<input type=\"\" value=\"\" /> <button id=\"button\" type=\"button\">推送</button>
</div>
</div>
<script src=\"http://code.jquery.com/jquery-2.1.1.min.js\"></script>
<script 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(); // 随机数字
// 创建对象socket
var 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(
`<p style=\"text-align: right;\"><span style=\"color:chocolate;\">${data.msg}</span>:手机客户端</p>`
)
} else if (data.code == 9001) {
$(\'#content\').append(`<p style=\"color:#a09b9b;text-align:center;\" >联接取得成功</p>`);
}
console.log(event)
};
// 监视不正确
webSocket.onerror = function(event) {
console.log(event)
$(\'#content\').append(`<p style=\"color:#a09b9b;text-align:center;\" >联接不正确</p>`);
clearInterval();
};
// 推送信息
$(\'#button\').click(() => {
let v = $(\'input\').val();
if (v) {
pushData.code = 9002;
pushData.msg = v;
webSocket.send(JSON.stringify(pushData));
$(\'#content\').append(
`<p>服务器端:<span style=\"color: blueviolet;\">${v}</span></p>`
)
$(\'input\').val(\'\');
}
})
function interval() {
time = setInterval(() => {
pushData.code = 9003;
pushData.msg = \'心率\';
webSocket.send(JSON.stringify(pushData));
}, 5000);
}
function clearInterval() {
clearInterval(time);
}
})
</script>
</body>
</html>
手机客户端
<!DOCTYPE html>
<html>
<head>
<meta charset=\"utf-8\">
<title>客户端</title>
<style type=\"text/css\">
#client {
margin: 0px auto;
width: 500px;
}
input {
width: 80%;
height: 40px;
border-radius: 5px;
border-color: #CCCCCC;
outline: #01FA01;
}
#button {
width: 84px;
height: 46px;
background-color: #5af3a5;
color: #fff;
font-size: 20px;
border-radius: 5px;
border: none;
box-shadow: 1px 1px 1px 1px #ccc;
cursor: pointer;
outline: #01FA01;
}
</style>
</head>
<body>
<div id=\"client\">
<h1 style=\"text-align: center;\">手机客户端推送信息</h1>
<div id=\"content\" contenteditable=true
style=\"width: 500px;height: 500px;margin: 0px auto;border: 1px solid #000000;padding: 10px;border-radius: 10px;overflow: auto;\">
</div>
<div style=\"padding: 5px;0px\">
<input type=\"\" value=\"\" /> <button id=\"button\" type=\"button\">推送</button>
</div>
</div>
<script src=\"http://code.jquery.com/jquery-2.1.1.min.js\"></script>
<script 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(); // 随机数字
// 创建对象socket
var 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(
`<p style=\"text-align: right;\"><span style=\"color:chocolate;\">${data.msg}</span>:服务器端</p>`
)
} else if (data.code == 9001) {
$(\'#content\').append(`<p style=\"color:#a09b9b;text-align:center;\" >联接取得成功</p>`);
}
console.log(event)
};
// 监视不正确
webSocket.onerror = function(event) {
console.log(event)
$(\'#content\').append(`<p style=\"color:#a09b9b;text-align:center;\" >联接不正确</p>`);
clearInterval();
};
// 推送信息
$(\'#button\').click(() => {
let v = $(\'input\').val();
if (v) {
pushData.code = 9002;
pushData.msg = v;
webSocket.send(JSON.stringify(pushData));
$(\'#content\').append(
`<p>手机客户端:<span style=\"color: blueviolet;\">${v}</span></p>`
)
$(\'input\').val(\'\');
}
})
function interval() {
time = setInterval(() => {
pushData.code = 9003;
pushData.msg = \'心率\';
webSocket.send(JSON.stringify(pushData));
}, 5000);
}
function clearInterval() {
clearInterval(time);
}
})
</script>
</body>
</html>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。