SpringBoot+vue+websocket的一个小demo,很粗糙,后期优化; 参考:https://www.cnblogs.com/badaoliumangqizhi/p/14485676.html
公司需要使用websocket做一个需求,因为以前没有接触过,找了一篇文章,根据文章改了一下案例,一个小demo;
pom.xml引入websocket
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置websocket
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
创建Client对象,存储session和每个用户不同的uri
@Data
public class WebSocketClient {
private Session session;
private String uri;
}
编写service类,用于发送消息到前端
package com.ruoyi.blog.websocket;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint(value = "/websocketdemo/{userName}")
@Component
@Slf4j
public class WebSocketService {
private static int onlineCount = 0;
private static ConcurrentHashMap<String, WebSocketClient> webSocketMap = new ConcurrentHashMap<>();
private Session session;
private String userName = "";
@OnOpen
public void onOpen(Session session, @PathParam("userName") String userName) {
log.info("map:{},session:{},username:{}", webSocketMap.toString(), session, userName);
if (!webSocketMap.containsKey(userName)) {
addOnlineCount();
}
this.session = session;
this.userName = userName;
WebSocketClient client = new WebSocketClient();
client.setSession(session);
client.setUri(session.getRequestURI().toString());
webSocketMap.put(userName, client);
log.info("用户连接:" + userName + ",当前在线人数为:" + getOnlineCount());
try {
sendMessage("来自后台的反馈:连接成功");
} catch (IOException e) {
log.error("用户:" + userName + ",网络异常!!!!!!");
}
}
@OnClose
public void onClose() {
if (webSocketMap.containsKey(userName)) {
webSocketMap.remove(userName);
if (webSocketMap.size() > 0) {
subOnlineCount();
}
}
log.info("----------------------------------------------------------------------------");
log.info(userName + "用户退出,当前在线人数为:" + getOnlineCount());
}
@OnMessage
public void onMessage(String message, Session session) {
log.info("收到用户消息:" + userName + ",报文:" + message);
log.info("session:{}", session);
sendMessage(userName, message);
if (StringUtils.isNotBlank(message)) {
}
}
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:" + this.userName + ",原因:" + error.getMessage());
error.printStackTrace();
}
public void sendMessage(String message) throws IOException {
synchronized (session) {
this.session.getBasicRemote().sendText(message);
}
}
public static void sendMessage(String userName, String message) {
webSocketMap.forEach((key, value) -> log.info("map中的数据为:{},{}", key, value));
try {
WebSocketClient webSocketClient = webSocketMap.get(userName);
if (webSocketClient != null) {
log.info("休眠" + message.length() + "秒开始");
try {
int i = message.length() * 1000;
if (i != 0) {
Thread.sleep(i);
}
} catch (InterruptedException e) {
}
log.info("休眠" + message.length() + "秒结束");
StringBuilder sb = new StringBuilder(message);
webSocketClient.getSession().getBasicRemote().sendText(sb.reverse().toString());
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketService.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketService.onlineCount--;
}
public static void setOnlineCount(int onlineCount) {
WebSocketService.onlineCount = onlineCount;
}
public static ConcurrentHashMap<String, WebSocketClient> getWebSocketMap() {
return webSocketMap;
}
public static void setWebSocketMap(ConcurrentHashMap<String, WebSocketClient> webSocketMap) {
WebSocketService.webSocketMap = webSocketMap;
}
public Session getSession() {
return session;
}
public void setSession(Session session) {
this.session = session;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
因为参考老哥的类中方法太多,业务用不上,只用到了一些;
主要是客户端连接成功,客户端断开,客户端连接异常;
业务主要是传递一些信息到controller。然后异步调用处理方法,得到结果后调用WebSocketService中的方法向前端发送数据;
前端组件
<template>
<div>
<el-button @click="sendDataToServer">给后台发送消息</el-button>
用户:
<el-input v-model="userName" readonly></el-input>
消息:
<el-input v-model="message"></el-input>
</div>
</template>
<script>
import {sendMessage} from '@/api/oss'
export default {
name: "WebSocket",
data() {
return {
// ws是否启动
wsIsRun: false,
// 定义ws对象
webSocket: null,
// ws请求链接(类似于ws后台地址)
ws: '',
// ws定时器
wsTimer: null,
message: undefined,
userName: "itadmin",
}
},
async mounted() {
this.wsIsRun = true
this.wsInit()
},
methods: {
sendDataToServer() {
console.log(this.webSocket);
if (this.webSocket.readyState === 1) {
sendMessage({name: this.userName, phone: this.message});
// this.webSocket.send(this.message)
} else {
throw Error('服务未连接')
}
},
/**
* 初始化ws
*/
wsInit() {
const wsuri = `ws://localhost:8080/websocketdemo/${this.userName}`
this.ws = wsuri
if (!this.wsIsRun) return
// 销毁ws
this.wsDestroy()
// 初始化ws
this.webSocket = new WebSocket(this.ws)
// ws连接建立时触发
this.webSocket.addEventListener('open', this.wsOpenHanler)
// ws服务端给客户端推送消息
this.webSocket.addEventListener('message', this.wsMessageHanler)
// ws通信发生错误时触发
this.webSocket.addEventListener('error', this.wsErrorHanler)
// ws关闭时触发
this.webSocket.addEventListener('close', this.wsCloseHanler)
// 检查ws连接状态,readyState值为0表示尚未连接,1表示建立连接,2正在关闭连接,3已经关闭或无法打开
clearInterval(this.wsTimer)
this.wsTimer = setInterval(() => {
if (this.webSocket.readyState === 1) {
clearInterval(this.wsTimer)
} else {
console.log('ws建立连接失败')
this.wsInit()
}
}, 3000)
},
wsOpenHanler(event) {
console.log('ws建立连接成功')
},
wsMessageHanler(e) {
console.log('接受到消息:' + e.data)
//const redata = JSON.parse(e.data)
//console.log(redata)
},
/**
* ws通信发生错误
*/
wsErrorHanler(event) {
console.log(event, '通信发生错误')
this.wsInit()
},
/**
* ws关闭
*/
wsCloseHanler(event) {
console.log(event, 'ws关闭')
this.wsInit()
},
/**
* 销毁ws
*/
wsDestroy() {
if (this.webSocket !== null) {
this.webSocket.removeEventListener('open', this.wsOpenHanler)
this.webSocket.removeEventListener('message', this.wsMessageHanler)
this.webSocket.removeEventListener('error', this.wsErrorHanler)
this.webSocket.removeEventListener('close', this.wsCloseHanler)
this.webSocket.close()
this.webSocket = null
clearInterval(this.wsTimer)
}
},
}
}
</script>
<style scoped>
</style>
|