1、前端引入websocket
2、实现预警数据通过websocket统计在右上角 3、使用redis记录websocket客户端用户
This commit is contained in:
parent
472af60970
commit
05cd60971c
|
|
@ -164,6 +164,25 @@ public class RedisService {
|
||||||
return redisTemplate.opsForSet().members(key);
|
return redisTemplate.opsForSet().members(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set中移除指定元素
|
||||||
|
* @param key redis键
|
||||||
|
* @param value set值
|
||||||
|
* @param <T> obj
|
||||||
|
* @return 删除数量
|
||||||
|
*/
|
||||||
|
public <T> Long removeSet(String key, T value) {
|
||||||
|
Long size = null;
|
||||||
|
try {
|
||||||
|
size = redisTemplate.opsForSet().remove(key, value);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存Map
|
* 缓存Map
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
import org.springframework.scheduling.annotation.EnableAsync;
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
|
@ -24,6 +25,7 @@ import java.lang.annotation.*;
|
||||||
@Import({ ApplicationConfig.class, FeignAutoConfiguration.class })
|
@Import({ ApplicationConfig.class, FeignAutoConfiguration.class })
|
||||||
//自定义bean扫描,添加xjs路径下的bean
|
//自定义bean扫描,添加xjs路径下的bean
|
||||||
@ComponentScan(basePackages = {"com.ruoyi","com.xjs"})
|
@ComponentScan(basePackages = {"com.ruoyi","com.xjs"})
|
||||||
|
@EnableTransactionManagement
|
||||||
public @interface EnableCustomConfig
|
public @interface EnableCustomConfig
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ VUE_APP_TITLE = 管理平台
|
||||||
# 开发环境配置
|
# 开发环境配置
|
||||||
ENV = 'development'
|
ENV = 'development'
|
||||||
|
|
||||||
# 若依管理系统/开发环境
|
# 管理系统/开发环境
|
||||||
VUE_APP_BASE_API = '/dev-api'
|
VUE_APP_BASE_API = '/dev-api'
|
||||||
|
|
||||||
# 路由懒加载
|
# 路由懒加载
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="navbar">
|
<div class="navbar">
|
||||||
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
|
||||||
|
<hamburger id="hamburger-container" :is-active="sidebar.opened" class="hamburger-container"
|
||||||
|
@toggleClick="toggleSideBar"/>
|
||||||
|
|
||||||
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
|
<breadcrumb id="breadcrumb-container" class="breadcrumb-container" v-if="!topNav"/>
|
||||||
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
|
<top-nav id="topmenu-container" class="topmenu-container" v-if="topNav"/>
|
||||||
|
|
||||||
<div class="right-menu">
|
<div class="right-menu">
|
||||||
|
<el-badge :value="warnData.count" class=" hover-effect share-button">
|
||||||
|
<el-button type="warning" icon="el-icon-check" circle style="max-width: 22px;max-height: 22px;"></el-button>
|
||||||
|
</el-badge>
|
||||||
|
|
||||||
<template v-if="device!=='mobile'">
|
<template v-if="device!=='mobile'">
|
||||||
<search id="header-search" class="right-menu-item"/>
|
<search id="header-search" class="right-menu-item"/>
|
||||||
|
|
||||||
<!--todo 右上角添加信息提示等功能-->
|
|
||||||
|
|
||||||
<screenfull id="screenfull" class="right-menu-item hover-effect"/>
|
<screenfull id="screenfull" class="right-menu-item hover-effect"/>
|
||||||
|
|
||||||
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
<el-tooltip content="布局大小" effect="dark" placement="bottom">
|
||||||
|
|
@ -19,6 +23,8 @@
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
<img :src="avatar" class="user-avatar">
|
<img :src="avatar" class="user-avatar">
|
||||||
|
|
@ -62,11 +68,19 @@ export default {
|
||||||
RuoYiGit,
|
RuoYiGit,
|
||||||
RuoYiDoc
|
RuoYiDoc
|
||||||
},
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
warnData: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
'sidebar',
|
'sidebar',
|
||||||
'avatar',
|
'avatar',
|
||||||
'device'
|
'device',
|
||||||
|
"$socket",
|
||||||
]),
|
]),
|
||||||
setting: {
|
setting: {
|
||||||
get() {
|
get() {
|
||||||
|
|
@ -85,7 +99,21 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.$socket.registerCallBack(
|
||||||
|
"apiWarning",
|
||||||
|
this.getData
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
getData(data) {
|
||||||
|
if (data) {
|
||||||
|
this.warnData = data
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
toggleSideBar() {
|
toggleSideBar() {
|
||||||
this.$store.dispatch('app/toggleSideBar')
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
},
|
},
|
||||||
|
|
@ -98,13 +126,35 @@ export default {
|
||||||
this.$store.dispatch('LogOut').then(() => {
|
this.$store.dispatch('LogOut').then(() => {
|
||||||
location.href = '/index';
|
location.href = '/index';
|
||||||
})
|
})
|
||||||
}).catch(() => {});
|
}).catch(() => {
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
// 在组件销毁的时候, 进行回调函数的取消
|
||||||
|
this.$socket.unRegisterCallBack();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.share-button {
|
||||||
|
margin-right: 23px;
|
||||||
|
color: #5a5e66;
|
||||||
|
padding-bottom: 22px;
|
||||||
|
|
||||||
|
&.hover-effect {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, .025)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ import ResizeMixin from './mixin/ResizeHandler'
|
||||||
import {mapState} from 'vuex'
|
import {mapState} from 'vuex'
|
||||||
import variables from '@/assets/styles/variables.scss'
|
import variables from '@/assets/styles/variables.scss'
|
||||||
|
|
||||||
|
import SocketService from "@/utils/socket-server";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -54,11 +56,30 @@ export default {
|
||||||
return variables;
|
return variables;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
created() {
|
||||||
|
this.connectWebsocket();
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
//连接websocket
|
||||||
|
connectWebsocket() {
|
||||||
|
if (!this.$socket) {
|
||||||
|
SocketService.Instance.connect();
|
||||||
|
this.$store.dispatch("app/set$Socket", SocketService.Instance);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
handleClickOutside() {
|
handleClickOutside() {
|
||||||
this.$store.dispatch('app/closeSideBar', {withoutAnimation: false})
|
this.$store.dispatch('app/closeSideBar', {withoutAnimation: false})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.$socket) {
|
||||||
|
this.$socket.closeWebsocket();
|
||||||
|
this.$store.dispatch("app/set$Socket", null);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,6 @@ const getters = {
|
||||||
topbarRouters:state => state.permission.topbarRouters,
|
topbarRouters:state => state.permission.topbarRouters,
|
||||||
defaultRoutes:state => state.permission.defaultRoutes,
|
defaultRoutes:state => state.permission.defaultRoutes,
|
||||||
sidebarRouters:state => state.permission.sidebarRouters,
|
sidebarRouters:state => state.permission.sidebarRouters,
|
||||||
|
$socket: state => state.app.$socket,
|
||||||
}
|
}
|
||||||
export default getters
|
export default getters
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@ const state = {
|
||||||
withoutAnimation: false
|
withoutAnimation: false
|
||||||
},
|
},
|
||||||
device: 'desktop',
|
device: 'desktop',
|
||||||
size: Cookies.get('size') || 'medium'
|
size: Cookies.get('size') || 'medium',
|
||||||
|
// websocket实例
|
||||||
|
$socket: null
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
|
@ -30,6 +32,9 @@ const mutations = {
|
||||||
SET_SIZE: (state, size) => {
|
SET_SIZE: (state, size) => {
|
||||||
state.size = size
|
state.size = size
|
||||||
Cookies.set('size', size)
|
Cookies.set('size', size)
|
||||||
|
},
|
||||||
|
SET_$SOCKET: (state, socket) => {
|
||||||
|
state.$socket = socket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,6 +50,9 @@ const actions = {
|
||||||
},
|
},
|
||||||
setSize({commit}, size) {
|
setSize({commit}, size) {
|
||||||
commit('SET_SIZE', size)
|
commit('SET_SIZE', size)
|
||||||
|
},
|
||||||
|
set$Socket({commit}, socket) {
|
||||||
|
commit('SET_$SOCKET', socket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,134 @@
|
||||||
|
import { Message } from "element-ui";
|
||||||
|
import store from '@/store'
|
||||||
|
// let wsUrl = 'ws://127.0.0.1:9002/warning/api';
|
||||||
|
|
||||||
|
export default class SocketService {
|
||||||
|
/**
|
||||||
|
* 单例
|
||||||
|
*/
|
||||||
|
static instance = null;
|
||||||
|
static get Instance() {
|
||||||
|
if (!this.instance) {
|
||||||
|
this.instance = new SocketService();
|
||||||
|
}
|
||||||
|
return this.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 和服务端连接的socket对象
|
||||||
|
ws = null;
|
||||||
|
|
||||||
|
// 存储回调函数
|
||||||
|
callBackMapping = {};
|
||||||
|
|
||||||
|
// 标识是否连接成功
|
||||||
|
connected = false;
|
||||||
|
|
||||||
|
// 记录重试的次数
|
||||||
|
sendRetryCount = 0;
|
||||||
|
|
||||||
|
// 重新连接尝试的次数
|
||||||
|
connectRetryCount = 0;
|
||||||
|
|
||||||
|
// 是否手动关闭websocket连接
|
||||||
|
isManualClose = false
|
||||||
|
|
||||||
|
// 定义连接服务器的方法
|
||||||
|
connect() {
|
||||||
|
// 连接服务器
|
||||||
|
if (!window.WebSocket) {
|
||||||
|
return console.log("您的浏览器不支持WebSocket");
|
||||||
|
}
|
||||||
|
//网关转发
|
||||||
|
let wsUrl = 'ws://localhost:8080/warning/warning/api';
|
||||||
|
wsUrl += `/${store.getters.name}`
|
||||||
|
this.ws = new WebSocket(wsUrl)
|
||||||
|
|
||||||
|
// 连接成功的事件
|
||||||
|
this.ws.onopen = () => {
|
||||||
|
console.log("连接服务端成功了");
|
||||||
|
this.connected = true;
|
||||||
|
// 重置重新连接的次数
|
||||||
|
this.connectRetryCount = 0;
|
||||||
|
};
|
||||||
|
// 1.连接服务端失败
|
||||||
|
// 2.当连接成功之后, 服务器关闭的情况
|
||||||
|
this.ws.onclose = (event) => {
|
||||||
|
// e.code === 1000 表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
|
||||||
|
// e.code !== 1000 表示非正常关闭。
|
||||||
|
console.log("onclose event: ", event);
|
||||||
|
this.connected = false;
|
||||||
|
if (event && event.code !== 1000) {
|
||||||
|
console.log("连接服务端失败");
|
||||||
|
// 如果不是手动关闭,这里的重连会执行;如果调用了手动关闭函数,这里重连不会执行
|
||||||
|
this.connectRetryCount++;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.connect();
|
||||||
|
}, 500 * this.connectRetryCount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// 得到服务端发送过来的数据
|
||||||
|
this.ws.onmessage = (msg) => {
|
||||||
|
console.log("从服务端获取到了数据");
|
||||||
|
// 真正服务端发送过来的原始数据时在msg中的data字段
|
||||||
|
const recvData = JSON.parse(msg.data);
|
||||||
|
console.log(recvData)
|
||||||
|
const socketType = recvData.socketType;
|
||||||
|
if (this.callBackMapping[socketType]){
|
||||||
|
this.callBackMapping[socketType].call(this, recvData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回调函数的注册
|
||||||
|
registerCallBack(socketType, callBack) {
|
||||||
|
this.callBackMapping[socketType] = callBack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消某一个回调函数
|
||||||
|
unRegisterCallBack(socketType) {
|
||||||
|
this.callBackMapping[socketType] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 发送数据的方法
|
||||||
|
send(data) {
|
||||||
|
// 判断此时此刻有没有连接成功
|
||||||
|
if (this.connected) {
|
||||||
|
this.sendRetryCount = 0;
|
||||||
|
this.ws.send(JSON.stringify(data));
|
||||||
|
console.log('xxxxxxxxxxxx')
|
||||||
|
} else if (!this.isManualClose) {
|
||||||
|
console.log('=============')
|
||||||
|
this.sendRetryCount++;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.send(data);
|
||||||
|
}, this.sendRetryCount * 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动关闭websocket (这里手动关闭会执行onclose事件)
|
||||||
|
closeWebsocket() {
|
||||||
|
if (this.ws) {
|
||||||
|
try {
|
||||||
|
this.ws.close(); // 关闭websocket
|
||||||
|
this.ws = null
|
||||||
|
this.callBackMapping = {}
|
||||||
|
this.connected = false
|
||||||
|
this.sendRetryCount = 0
|
||||||
|
this.connectRetryCount = 0
|
||||||
|
this.isManualClose = true
|
||||||
|
this.instance = null
|
||||||
|
SocketService.instance = null
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const MessageEvent = { // onmessage回调函数的event
|
||||||
|
data: { // websocket通讯接收到的数据
|
||||||
|
socketType: '', // websocket双方通讯的名称
|
||||||
|
data: {}, // 返回的真实数据
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,11 @@ public class RedisConst {
|
||||||
*/
|
*/
|
||||||
public static final String HOT = "hot";
|
public static final String HOT = "hot";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* websocket常量key
|
||||||
|
*/
|
||||||
|
public static final String WEBSOCKET= "WEBSOCKET";
|
||||||
|
|
||||||
|
|
||||||
//-------------------有效时间-----------------------
|
//-------------------有效时间-----------------------
|
||||||
public static final Integer TRAN_DICT_EXPIRE = 7; //天
|
public static final Integer TRAN_DICT_EXPIRE = 7; //天
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package com.xjs.controller;
|
package com.xjs.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.domain.R;
|
||||||
import com.ruoyi.common.core.utils.poi.ExcelUtil;
|
import com.ruoyi.common.core.utils.poi.ExcelUtil;
|
||||||
|
|
@ -8,16 +9,23 @@ import com.ruoyi.common.core.web.domain.AjaxResult;
|
||||||
import com.ruoyi.common.core.web.page.TableDataInfo;
|
import com.ruoyi.common.core.web.page.TableDataInfo;
|
||||||
import com.ruoyi.common.log.annotation.Log;
|
import com.ruoyi.common.log.annotation.Log;
|
||||||
import com.ruoyi.common.log.enums.BusinessType;
|
import com.ruoyi.common.log.enums.BusinessType;
|
||||||
|
import com.ruoyi.common.redis.service.RedisService;
|
||||||
import com.ruoyi.common.security.annotation.RequiresPermissions;
|
import com.ruoyi.common.security.annotation.RequiresPermissions;
|
||||||
import com.xjs.domain.ApiRecord;
|
import com.xjs.domain.ApiRecord;
|
||||||
import com.xjs.domain.ApiWarning;
|
import com.xjs.domain.ApiWarning;
|
||||||
|
import com.xjs.server.WebSocketServer;
|
||||||
import com.xjs.service.ApiWarningService;
|
import com.xjs.service.ApiWarningService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.xjs.consts.RedisConst.WEBSOCKET;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author xiejs
|
* @author xiejs
|
||||||
|
|
@ -30,6 +38,8 @@ public class ApiWarningController extends BaseController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ApiWarningService apiWarningService;
|
private ApiWarningService apiWarningService;
|
||||||
|
@Autowired
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程保存 apiRecord
|
* 远程保存 apiRecord
|
||||||
|
|
@ -66,17 +76,41 @@ public class ApiWarningController extends BaseController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程保存api预警信息
|
* 远程保存api预警信息并websocket推送
|
||||||
*
|
*
|
||||||
* @param apiWarning 预警实体类
|
* @param apiWarning 预警实体类
|
||||||
* @return R
|
* @return R
|
||||||
*/
|
*/
|
||||||
@PostMapping("saveApiwarningForRPC")
|
@PostMapping("saveApiwarningForRPC")
|
||||||
|
@Transactional
|
||||||
public R<ApiWarning> saveApiWarningForRPC(@RequestBody ApiWarning apiWarning) {
|
public R<ApiWarning> saveApiWarningForRPC(@RequestBody ApiWarning apiWarning) {
|
||||||
boolean save = apiWarningService.save(apiWarning);
|
boolean save = apiWarningService.save(apiWarning);
|
||||||
|
|
||||||
|
this.websocketPush(apiWarning);
|
||||||
|
|
||||||
return save ? R.ok() : R.fail();
|
return save ? R.ok() : R.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* websocket推送
|
||||||
|
*/
|
||||||
|
private void websocketPush(ApiWarning apiWarning) {
|
||||||
|
long count = apiWarningService.count();
|
||||||
|
Set<String> cacheSet = redisService.getCacheSet(WEBSOCKET);
|
||||||
|
JSONObject jsonData =new JSONObject();
|
||||||
|
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(apiWarning);
|
||||||
|
jsonData.put("count", count);
|
||||||
|
jsonData.put("data", jsonObject.toJSONString());
|
||||||
|
jsonData.put("socketType", "apiWarning");
|
||||||
|
for (String userId : cacheSet) {
|
||||||
|
try {
|
||||||
|
WebSocketServer.sendInfo(jsonData.toString(),userId);
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询api预警列表
|
* 查询api预警列表
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,23 @@
|
||||||
package com.xjs.server;
|
package com.xjs.server;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.ruoyi.common.redis.service.RedisService;
|
||||||
|
import com.xjs.service.ApiWarningService;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.websocket.*;
|
import javax.websocket.*;
|
||||||
import javax.websocket.server.PathParam;
|
import javax.websocket.server.PathParam;
|
||||||
import javax.websocket.server.ServerEndpoint;
|
import javax.websocket.server.ServerEndpoint;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import static com.xjs.consts.RedisConst.WEBSOCKET;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* api预警websocket
|
* api预警websocket
|
||||||
*
|
*
|
||||||
|
|
@ -17,9 +25,25 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
* @since 2022-01-13
|
* @since 2022-01-13
|
||||||
*/
|
*/
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@ServerEndpoint("warning/api/{userId}")
|
@ServerEndpoint("/warning/api/{userId}")
|
||||||
@Component
|
@Component
|
||||||
public class WebSocketServer {
|
public class WebSocketServer {
|
||||||
|
/**
|
||||||
|
* 之所有需要set注入,因为WebSocketServer是静态类,需要注入属性就需要用set注入
|
||||||
|
*/
|
||||||
|
private static RedisService redisService;
|
||||||
|
@Autowired
|
||||||
|
public void setRedisService(RedisService redisService) {
|
||||||
|
WebSocketServer.redisService = redisService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ApiWarningService apiWarningService;
|
||||||
|
@Autowired
|
||||||
|
public void setApiWarningService(ApiWarningService apiWarningService) {
|
||||||
|
WebSocketServer.apiWarningService = apiWarningService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
* 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
||||||
*/
|
*/
|
||||||
|
|
@ -56,12 +80,21 @@ public class WebSocketServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());
|
log.info("用户连接:" + userId + ",当前在线人数为:" + getOnlineCount());
|
||||||
|
Set<String> set = new HashSet<>();
|
||||||
|
set.add(userId);
|
||||||
|
redisService.setCacheSet(WEBSOCKET, set);
|
||||||
|
|
||||||
|
long count = apiWarningService.count();
|
||||||
|
JSONObject jsonData =new JSONObject();
|
||||||
|
jsonData.put("count", count);
|
||||||
|
jsonData.put("socketType", "apiWarning");
|
||||||
|
jsonData.put("data", "{}");
|
||||||
try {
|
try {
|
||||||
sendMessage("连接成功");
|
sendMessage(jsonData.toJSONString());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("用户:" + userId + ",网络异常!!!!!!");
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,6 +106,9 @@ public class WebSocketServer {
|
||||||
webSocketMap.remove(userId);
|
webSocketMap.remove(userId);
|
||||||
//从set中删除
|
//从set中删除
|
||||||
subOnlineCount();
|
subOnlineCount();
|
||||||
|
|
||||||
|
//退出移出用户
|
||||||
|
redisService.removeSet(WEBSOCKET, this.userId);
|
||||||
}
|
}
|
||||||
log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
|
log.info("用户退出:" + userId + ",当前在线人数为:" + getOnlineCount());
|
||||||
}
|
}
|
||||||
|
|
@ -107,6 +143,7 @@ public class WebSocketServer {
|
||||||
@OnError
|
@OnError
|
||||||
public void onError(Session session, Throwable error) {
|
public void onError(Session session, Throwable error) {
|
||||||
log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
|
log.error("用户错误:" + this.userId + ",原因:" + error.getMessage());
|
||||||
|
redisService.removeSet(WEBSOCKET, this.userId);
|
||||||
error.printStackTrace();
|
error.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue