diff --git a/im-admin-ui/.env.development b/im-admin-ui/.env.development
index 59875df..2591860 100644
--- a/im-admin-ui/.env.development
+++ b/im-admin-ui/.env.development
@@ -15,8 +15,5 @@ VITE_APP_PORT = 3000
# 客户端id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
-# websocket 开关 默认使用sse推送
-VITE_APP_WEBSOCKET = false
-
-# sse 开关
-VITE_APP_SSE = true
+# websocket 开关
+VITE_APP_WEBSOCKET = true
diff --git a/im-admin-ui/.env.production b/im-admin-ui/.env.production
index b02e18a..1b3e46e 100644
--- a/im-admin-ui/.env.production
+++ b/im-admin-ui/.env.production
@@ -13,8 +13,6 @@ VITE_APP_BASE_API = 'https://www.boxim.online/adm/api'
# 客户端id
VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
-# websocket 开关 默认使用sse推送
-VITE_APP_WEBSOCKET = false
+# websocket 开关
+VITE_APP_WEBSOCKET = true
-# sse 开关
-VITE_APP_SSE = true
diff --git a/im-admin-ui/src/api/login.ts b/im-admin-ui/src/api/login.ts
index c7c291e..b6955de 100644
--- a/im-admin-ui/src/api/login.ts
+++ b/im-admin-ui/src/api/login.ts
@@ -51,10 +51,6 @@ export function register(data: any) {
* 注销
*/
export function logout() {
- request({
- url: '/resource/sse/close',
- method: 'get'
- });
return request({
url: '/auth/logout',
method: 'post'
diff --git a/im-admin-ui/src/layout/index.vue b/im-admin-ui/src/layout/index.vue
index ce47a30..8ef0af9 100644
--- a/im-admin-ui/src/layout/index.vue
+++ b/im-admin-ui/src/layout/index.vue
@@ -27,7 +27,7 @@ import { AppMain, Navbar, Settings, TagsView } from './components';
import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings';
import { initWebSocket } from '@/utils/websocket';
-import { initSSE } from "@/utils/sse";
+
const settingsStore = useSettingsStore();
const theme = computed(() => settingsStore.theme);
@@ -72,10 +72,6 @@ onMounted(() => {
initWebSocket(protocol + window.location.host + import.meta.env.VITE_APP_BASE_API + '/resource/websocket');
});
-onMounted(() => {
- initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
-});
-
const handleClickOutside = () => {
useAppStore().closeSideBar({ withoutAnimation: false });
};
diff --git a/im-admin-ui/src/types/env.d.ts b/im-admin-ui/src/types/env.d.ts
index 1fb9f62..777c858 100644
--- a/im-admin-ui/src/types/env.d.ts
+++ b/im-admin-ui/src/types/env.d.ts
@@ -19,7 +19,6 @@ interface ImportMetaEnv {
VITE_APP_RSA_PRIVATE_KEY: string;
VITE_APP_CLIENT_ID: string;
VITE_APP_WEBSOCKET: string;
- VITE_APP_SSE: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
diff --git a/im-admin-ui/src/utils/sse.ts b/im-admin-ui/src/utils/sse.ts
deleted file mode 100644
index 9174f0d..0000000
--- a/im-admin-ui/src/utils/sse.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { getToken } from '@/utils/auth';
-import { ElNotification } from 'element-plus';
-import useNoticeStore from '@/store/modules/notice';
-
-// 初始化
-export const initSSE = (url: any) => {
- if (import.meta.env.VITE_APP_SSE === 'false') {
- return;
- }
-
- url = url + '?Authorization=Bearer ' + getToken() + '&clientid=' + import.meta.env.VITE_APP_CLIENT_ID
- const {
- data,
- error
- } = useEventSource(url, [], {
- autoReconnect: {
- retries: 10,
- delay: 3000,
- onFailed() {
- console.log('Failed to connect after 10 retries');
- }
- }
- });
-
- watch(error, () => {
- console.log('SSE connection error:', error.value);
- error.value = null;
- });
-
- watch(data, () => {
- if (!data.value) return;
- useNoticeStore().addNotice({
- message: data.value,
- read: false,
- time: new Date().toLocaleString()
- });
- ElNotification({
- title: '消息',
- message: data.value,
- type: 'success',
- duration: 3000
- });
- data.value = null;
- });
-};
diff --git a/im-admin-ui/src/views/login.vue b/im-admin-ui/src/views/login.vue
index a04cbc2..e3fc8fd 100644
--- a/im-admin-ui/src/views/login.vue
+++ b/im-admin-ui/src/views/login.vue
@@ -49,7 +49,7 @@ import { getCodeImg, getTenantList } from '@/api/login';
import { useUserStore } from '@/store/modules/user';
import { LoginData, TenantVO } from '@/api/types';
import { to } from 'await-to-js';
-import logo from '@/assets/logo/logo.png';
+
const userStore = useUserStore();
const router = useRouter();
@@ -73,9 +73,9 @@ const loginRules: ElFormRules = {
const codeUrl = ref('');
const loading = ref(false);
// 验证码开关
-const captchaEnabled = ref(true);
+const captchaEnabled = ref(false);
// 租户开关
-const tenantEnabled = ref(true);
+const tenantEnabled = ref(false);
// 注册开关
const register = ref(false);
diff --git a/im-admin/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java b/im-admin/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
index 1fe8eae..870cee0 100644
--- a/im-admin/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
+++ b/im-admin/ruoyi-admin/src/main/java/org/dromara/web/controller/AuthController.java
@@ -23,10 +23,10 @@ import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
-import org.dromara.common.social.utils.SocialUtils;
-import org.dromara.common.sse.dto.SseMessageDto;
-import org.dromara.common.sse.utils.SseMessageUtils;
+import org.dromara.common.social.utils.SocialUtils;;
import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.common.websocket.dto.WebSocketMessageDto;
+import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.system.domain.bo.SysTenantBo;
import org.dromara.system.domain.vo.SysClientVo;
import org.dromara.system.domain.vo.SysTenantVo;
@@ -102,10 +102,10 @@ public class AuthController {
Long userId = LoginHelper.getUserId();
scheduledExecutorService.schedule(() -> {
- SseMessageDto dto = new SseMessageDto();
+ WebSocketMessageDto dto = new WebSocketMessageDto();
dto.setMessage("欢迎登录盒子IM后台管理系统");
- dto.setUserIds(List.of(userId));
- SseMessageUtils.publishMessage(dto);
+ dto.setSessionKeys(List.of(userId));
+ WebSocketUtils.publishMessage(dto);
}, 5, TimeUnit.SECONDS);
return R.ok(loginVo);
}
diff --git a/im-admin/ruoyi-admin/src/main/resources/application.yml b/im-admin/ruoyi-admin/src/main/resources/application.yml
index e851c3b..ded7f00 100644
--- a/im-admin/ruoyi-admin/src/main/resources/application.yml
+++ b/im-admin/ruoyi-admin/src/main/resources/application.yml
@@ -213,16 +213,10 @@ lock4j:
# 分布式锁的超时时间,默认为 30 秒
expire: 30000
-
---- # 默认/推荐使用sse推送
-sse:
- enabled: true
- path: /resource/sse
-
--- # websocket
websocket:
# 如果关闭 需要和前端开关一起关闭
- enabled: false
+ enabled: true
# 路径
path: /resource/websocket
# 设置访问源地址
diff --git a/im-admin/ruoyi-common/pom.xml b/im-admin/ruoyi-common/pom.xml
index a46c7c9..2b6f7e0 100644
--- a/im-admin/ruoyi-common/pom.xml
+++ b/im-admin/ruoyi-common/pom.xml
@@ -31,7 +31,6 @@
ruoyi-common-encrypt
ruoyi-common-tenant
ruoyi-common-websocket
- ruoyi-common-sse
ruoyi-common
diff --git a/im-admin/ruoyi-common/ruoyi-common-bom/pom.xml b/im-admin/ruoyi-common/ruoyi-common-bom/pom.xml
index 36d00b8..783fe3e 100644
--- a/im-admin/ruoyi-common/ruoyi-common-bom/pom.xml
+++ b/im-admin/ruoyi-common/ruoyi-common-bom/pom.xml
@@ -165,13 +165,6 @@
${revision}
-
-
- org.dromara
- ruoyi-common-sse
- ${revision}
-
-
diff --git a/im-admin/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/SseException.java b/im-admin/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/SseException.java
deleted file mode 100644
index a76e16d..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/exception/SseException.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package org.dromara.common.core.exception;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-import java.io.Serial;
-
-/**
- * sse 特制异常
- *
- * @author LionLi
- */
-@Data
-@EqualsAndHashCode(callSuper = true)
-@NoArgsConstructor
-@AllArgsConstructor
-public final class SseException extends RuntimeException {
-
- @Serial
- private static final long serialVersionUID = 1L;
-
- /**
- * 错误码
- */
- private Integer code;
-
- /**
- * 错误提示
- */
- private String message;
-
- /**
- * 错误明细,内部调试错误
- */
- private String detailMessage;
-
- public SseException(String message) {
- this.message = message;
- }
-
- public SseException(String message, Integer code) {
- this.message = message;
- this.code = code;
- }
-
- @Override
- public String getMessage() {
- return message;
- }
-
- public SseException setMessage(String message) {
- this.message = message;
- return this;
- }
-
- public SseException setDetailMessage(String detailMessage) {
- this.detailMessage = detailMessage;
- return this;
- }
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/im-admin/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java
index a4e921f..33175fa 100644
--- a/im-admin/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java
+++ b/im-admin/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java
@@ -11,7 +11,6 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.HttpStatus;
-import org.dromara.common.core.exception.SseException;
import org.dromara.common.core.utils.ServletUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StringUtils;
@@ -57,11 +56,7 @@ public class SecurityConfig implements WebMvcConfigurer {
try {
StpUtil.checkLogin();
} catch (NotLoginException e) {
- if (request.getRequestURI().contains("sse")) {
- throw new SseException(e.getMessage(), e.getCode());
- } else {
- throw e;
- }
+ throw e;
}
// 检查 header 与 param 里的 clientid 与 token 里的是否一致
@@ -70,8 +65,7 @@ public class SecurityConfig implements WebMvcConfigurer {
String clientId = StpUtil.getExtra(LoginHelper.CLIENT_KEY).toString();
if (!StringUtils.equalsAny(clientId, headerCid, paramCid)) {
// token 无效
- throw NotLoginException.newInstance(StpUtil.getLoginType(),
- "-100", "客户端ID与Token不匹配",
+ throw NotLoginException.newInstance(StpUtil.getLoginType(), "-100", "客户端ID与Token不匹配",
StpUtil.getTokenValue());
}
@@ -94,12 +88,9 @@ public class SecurityConfig implements WebMvcConfigurer {
public SaServletFilter getSaServletFilter() {
String username = SpringUtils.getProperty("spring.boot.admin.client.username");
String password = SpringUtils.getProperty("spring.boot.admin.client.password");
- return new SaServletFilter()
- .addInclude("/actuator", "/actuator/**")
- .setAuth(obj -> {
- SaHttpBasicUtil.check(username + ":" + password);
- })
- .setError(e -> SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED));
+ return new SaServletFilter().addInclude("/actuator", "/actuator/**").setAuth(obj -> {
+ SaHttpBasicUtil.check(username + ":" + password);
+ }).setError(e -> SaResult.error(e.getMessage()).setCode(HttpStatus.UNAUTHORIZED));
}
}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/pom.xml b/im-admin/ruoyi-common/ruoyi-common-sse/pom.xml
deleted file mode 100644
index ae44c98..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
- org.dromara
- ruoyi-common
- ${revision}
-
- 4.0.0
-
- ruoyi-common-sse
-
-
- ruoyi-common-sse 模块
-
-
-
-
- org.dromara
- ruoyi-common-core
-
-
- org.dromara
- ruoyi-common-redis
-
-
- org.dromara
- ruoyi-common-satoken
-
-
- org.dromara
- ruoyi-common-json
-
-
-
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java
deleted file mode 100644
index 0cf8054..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseAutoConfiguration.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.dromara.common.sse.config;
-
-import org.dromara.common.sse.controller.SseController;
-import org.dromara.common.sse.core.SseEmitterManager;
-import org.dromara.common.sse.listener.SseTopicListener;
-import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-
-/**
- * SSE 自动装配
- *
- * @author Lion Li
- */
-@AutoConfiguration
-@ConditionalOnProperty(value = "sse.enabled", havingValue = "true")
-@EnableConfigurationProperties(SseProperties.class)
-public class SseAutoConfiguration {
-
- @Bean
- public SseEmitterManager sseEmitterManager() {
- return new SseEmitterManager();
- }
-
- @Bean
- public SseTopicListener sseTopicListener() {
- return new SseTopicListener();
- }
-
- @Bean
- public SseController sseController(SseEmitterManager sseEmitterManager) {
- return new SseController(sseEmitterManager);
- }
-
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java
deleted file mode 100644
index ce4e173..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/config/SseProperties.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.dromara.common.sse.config;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * SSE 配置项
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties("sse")
-public class SseProperties {
-
- private Boolean enabled;
-
- /**
- * 路径
- */
- private String path;
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java
deleted file mode 100644
index e5331e4..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/controller/SseController.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.dromara.common.sse.controller;
-
-import cn.dev33.satoken.annotation.SaIgnore;
-import cn.dev33.satoken.stp.StpUtil;
-import lombok.RequiredArgsConstructor;
-import org.dromara.common.core.domain.R;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.sse.core.SseEmitterManager;
-import org.dromara.common.sse.dto.SseMessageDto;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-
-import java.util.List;
-
-/**
- * SSE 控制器
- *
- * @author Lion Li
- */
-@RestController
-@ConditionalOnProperty(value = "sse.enabled", havingValue = "true")
-@RequiredArgsConstructor
-public class SseController implements DisposableBean {
-
- private final SseEmitterManager sseEmitterManager;
-
- /**
- * 建立 SSE 连接
- */
- @GetMapping(value = "${sse.path}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
- public SseEmitter connect() {
- String tokenValue = StpUtil.getTokenValue();
- Long userId = LoginHelper.getUserId();
- return sseEmitterManager.connect(userId, tokenValue);
- }
-
- /**
- * 关闭 SSE 连接
- */
- @SaIgnore
- @GetMapping(value = "${sse.path}/close")
- public R close() {
- String tokenValue = StpUtil.getTokenValue();
- Long userId = LoginHelper.getUserId();
- sseEmitterManager.disconnect(userId, tokenValue);
- return R.ok();
- }
-
- /**
- * 向特定用户发送消息
- *
- * @param userId 目标用户的 ID
- * @param msg 要发送的消息内容
- */
- @GetMapping(value = "${sse.path}/send")
- public R send(Long userId, String msg) {
- SseMessageDto dto = new SseMessageDto();
- dto.setUserIds(List.of(userId));
- dto.setMessage(msg);
- sseEmitterManager.publishMessage(dto);
- return R.ok();
- }
-
- /**
- * 向所有用户发送消息
- *
- * @param msg 要发送的消息内容
- */
- @GetMapping(value = "${sse.path}/sendAll")
- public R send(String msg) {
- sseEmitterManager.publishAll(msg);
- return R.ok();
- }
-
- /**
- * 清理资源。此方法目前不执行任何操作,但避免因未实现而导致错误
- */
- @Override
- public void destroy() throws Exception {
- // 销毁时不需要做什么 此方法避免无用操作报错
- }
-
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java
deleted file mode 100644
index 0bfe0ca..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/core/SseEmitterManager.java
+++ /dev/null
@@ -1,145 +0,0 @@
-package org.dromara.common.sse.core;
-
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.redis.utils.RedisUtils;
-import org.dromara.common.sse.dto.SseMessageDto;
-import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Consumer;
-
-/**
- * 管理 Server-Sent Events (SSE) 连接
- *
- * @author Lion Li
- */
-@Slf4j
-public class SseEmitterManager {
-
- /**
- * 订阅的频道
- */
- private final static String SSE_TOPIC = "global:sse";
-
- private final static Map> USER_TOKEN_EMITTERS = new ConcurrentHashMap<>();
-
- /**
- * 建立与指定用户的 SSE 连接
- *
- * @param userId 用户的唯一标识符,用于区分不同用户的连接
- * @param token 用户的唯一令牌,用于识别具体的连接
- * @return 返回一个 SseEmitter 实例,客户端可以通过该实例接收 SSE 事件
- */
- public SseEmitter connect(Long userId, String token) {
- // 从 USER_TOKEN_EMITTERS 中获取或创建当前用户的 SseEmitter 映射表(ConcurrentHashMap)
- // 每个用户可以有多个 SSE 连接,通过 token 进行区分
- Map emitters = USER_TOKEN_EMITTERS.computeIfAbsent(userId, k -> new ConcurrentHashMap<>());
-
- // 创建一个新的 SseEmitter 实例,超时时间设置为 0 表示无限制
- SseEmitter emitter = new SseEmitter(0L);
-
- emitters.put(token, emitter);
-
- // 当 emitter 完成、超时或发生错误时,从映射表中移除对应的 token
- emitter.onCompletion(() -> emitters.remove(token));
- emitter.onTimeout(() -> emitters.remove(token));
- emitter.onError((e) -> emitters.remove(token));
-
- try {
- // 向客户端发送一条连接成功的事件
- emitter.send(SseEmitter.event().comment("connected"));
- } catch (IOException e) {
- // 如果发送消息失败,则从映射表中移除 emitter
- emitters.remove(token);
- }
- return emitter;
- }
-
- /**
- * 断开指定用户的 SSE 连接
- *
- * @param userId 用户的唯一标识符,用于区分不同用户的连接
- * @param token 用户的唯一令牌,用于识别具体的连接
- */
- public void disconnect(Long userId, String token) {
- Map emitters = USER_TOKEN_EMITTERS.get(userId);
- if (emitters != null) {
- try {
- emitters.get(token).send(SseEmitter.event().comment("disconnected"));
- } catch (Exception ignore) {
- }
- emitters.remove(token);
- }
- }
-
- /**
- * 订阅SSE消息主题,并提供一个消费者函数来处理接收到的消息
- *
- * @param consumer 处理SSE消息的消费者函数
- */
- public void subscribeMessage(Consumer consumer) {
- RedisUtils.subscribe(SSE_TOPIC, SseMessageDto.class, consumer);
- }
-
- /**
- * 向指定的用户会话发送消息
- *
- * @param userId 要发送消息的用户id
- * @param message 要发送的消息内容
- */
- public void sendMessage(Long userId, String message) {
- Map emitters = USER_TOKEN_EMITTERS.get(userId);
- if (emitters != null) {
- for (Map.Entry entry : emitters.entrySet()) {
- try {
- entry.getValue().send(SseEmitter.event()
- .name("message")
- .data(message));
- } catch (Exception e) {
- emitters.remove(entry.getKey());
- }
- }
- }
- }
-
- /**
- * 本机全用户会话发送消息
- *
- * @param message 要发送的消息内容
- */
- public void sendMessage(String message) {
- for (Long userId : USER_TOKEN_EMITTERS.keySet()) {
- sendMessage(userId, message);
- }
- }
-
- /**
- * 发布SSE订阅消息
- *
- * @param sseMessageDto 要发布的SSE消息对象
- */
- public void publishMessage(SseMessageDto sseMessageDto) {
- SseMessageDto broadcastMessage = new SseMessageDto();
- broadcastMessage.setMessage(sseMessageDto.getMessage());
- broadcastMessage.setUserIds(sseMessageDto.getUserIds());
- RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> {
- log.info("SSE发送主题订阅消息topic:{} session keys:{} message:{}",
- SSE_TOPIC, sseMessageDto.getUserIds(), sseMessageDto.getMessage());
- });
- }
-
- /**
- * 向所有的用户发布订阅的消息(群发)
- *
- * @param message 要发布的消息内容
- */
- public void publishAll(String message) {
- SseMessageDto broadcastMessage = new SseMessageDto();
- broadcastMessage.setMessage(message);
- RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> {
- log.info("SSE发送主题订阅消息topic:{} message:{}", SSE_TOPIC, message);
- });
- }
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java
deleted file mode 100644
index a2e1210..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/dto/SseMessageDto.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.dromara.common.sse.dto;
-
-import lombok.Data;
-
-import java.io.Serial;
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 消息的dto
- *
- * @author zendwang
- */
-@Data
-public class SseMessageDto implements Serializable {
-
- @Serial
- private static final long serialVersionUID = 1L;
-
- /**
- * 需要推送到的session key 列表
- */
- private List userIds;
-
- /**
- * 需要发送的消息
- */
- private String message;
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java
deleted file mode 100644
index 7a4dff1..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/listener/SseTopicListener.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.dromara.common.sse.listener;
-
-import cn.hutool.core.collection.CollUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.sse.core.SseEmitterManager;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.ApplicationArguments;
-import org.springframework.boot.ApplicationRunner;
-import org.springframework.core.Ordered;
-
-/**
- * SSE 主题订阅监听器
- *
- * @author Lion Li
- */
-@Slf4j
-public class SseTopicListener implements ApplicationRunner, Ordered {
-
- @Autowired
- private SseEmitterManager sseEmitterManager;
-
- /**
- * 在Spring Boot应用程序启动时初始化SSE主题订阅监听器
- *
- * @param args 应用程序参数
- * @throws Exception 初始化过程中可能抛出的异常
- */
- @Override
- public void run(ApplicationArguments args) throws Exception {
- sseEmitterManager.subscribeMessage((message) -> {
- log.info("SSE主题订阅收到消息session keys={} message={}", message.getUserIds(), message.getMessage());
- // 如果key不为空就按照key发消息 如果为空就群发
- if (CollUtil.isNotEmpty(message.getUserIds())) {
- message.getUserIds().forEach(key -> {
- sseEmitterManager.sendMessage(key, message.getMessage());
- });
- } else {
- sseEmitterManager.sendMessage(message.getMessage());
- }
- });
- log.info("初始化SSE主题订阅监听器成功");
- }
-
- @Override
- public int getOrder() {
- return -1;
- }
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java
deleted file mode 100644
index c6abdc8..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/java/org/dromara/common/sse/utils/SseMessageUtils.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package org.dromara.common.sse.utils;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.common.sse.core.SseEmitterManager;
-import org.dromara.common.sse.dto.SseMessageDto;
-
-/**
- * SSE工具类
- *
- * @author Lion Li
- */
-@Slf4j
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class SseMessageUtils {
-
- private final static SseEmitterManager MANAGER = SpringUtils.getBean(SseEmitterManager.class);
-
- /**
- * 向指定的WebSocket会话发送消息
- *
- * @param userId 要发送消息的用户id
- * @param message 要发送的消息内容
- */
- public static void sendMessage(Long userId, String message) {
- MANAGER.sendMessage(userId, message);
- }
-
- /**
- * 本机全用户会话发送消息
- *
- * @param message 要发送的消息内容
- */
- public static void sendMessage(String message) {
- MANAGER.sendMessage(message);
- }
-
- /**
- * 发布SSE订阅消息
- *
- * @param sseMessageDto 要发布的SSE消息对象
- */
- public static void publishMessage(SseMessageDto sseMessageDto) {
- MANAGER.publishMessage(sseMessageDto);
- }
-
- /**
- * 向所有的用户发布订阅的消息(群发)
- *
- * @param message 要发布的消息内容
- */
- public static void publishAll(String message) {
- MANAGER.publishAll(message);
- }
-
-}
diff --git a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/im-admin/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
deleted file mode 100644
index b809713..0000000
--- a/im-admin/ruoyi-common/ruoyi-common-sse/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ /dev/null
@@ -1 +0,0 @@
-org.dromara.common.sse.config.SseAutoConfiguration
diff --git a/im-admin/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java b/im-admin/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java
index 321c226..41031a0 100644
--- a/im-admin/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java
+++ b/im-admin/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/handler/GlobalExceptionHandler.java
@@ -9,10 +9,8 @@ import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
-import org.dromara.common.core.exception.SseException;
import org.dromara.common.core.exception.base.BaseException;
import org.dromara.common.core.utils.StreamUtils;
-import org.dromara.common.json.utils.JsonUtils;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
@@ -56,17 +54,6 @@ public class GlobalExceptionHandler {
return ObjectUtil.isNotNull(code) ? R.fail(code, e.getMessage()) : R.fail(e.getMessage());
}
- /**
- * 认证失败
- */
- @ResponseStatus(org.springframework.http.HttpStatus.UNAUTHORIZED)
- @ExceptionHandler(SseException.class)
- public String handleNotLoginException(SseException e, HttpServletRequest request) {
- String requestURI = request.getRequestURI();
- log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());
- return JsonUtils.toJsonString(R.fail(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源"));
- }
-
/**
* servlet异常
*/
diff --git a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java
index 3c409a9..215f14a 100644
--- a/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java
+++ b/im-admin/ruoyi-im/src/main/java/org/dromara/im/service/impl/ImUserServiceImpl.java
@@ -162,7 +162,7 @@ public class ImUserServiceImpl implements IImUserService {
@Override
public Long getDailyActiveUserCount() {
LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
- wrapper.ge(ImUser::getLastLoginTime, DateUtils.addMonths(new Date(), -1));
+ wrapper.ge(ImUser::getLastLoginTime, DateUtils.addDays(new Date(), -1));
return baseMapper.selectCount(wrapper);
}
@@ -174,19 +174,19 @@ public class ImUserServiceImpl implements IImUserService {
@Override
public Long getWeeklyActiveUserCount() {
LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
- wrapper.ge(ImUser::getLastLoginTime, DateUtils.addMonths(new Date(), -7));
+ wrapper.ge(ImUser::getLastLoginTime, DateUtils.addDays(new Date(), -7));
return baseMapper.selectCount(wrapper);
}
/**
- * 获取月活跃用户数量(最近30天)
+ * 获取月活跃用户数量(
*
* @return 月活跃用户数量
*/
@Override
public Long getMonthlyActiveUserCount() {
LambdaQueryWrapper wrapper = Wrappers.lambdaQuery();
- wrapper.ge(ImUser::getLastLoginTime, DateUtils.addMonths(new Date(), -30));
+ wrapper.ge(ImUser::getLastLoginTime, DateUtils.addDays(new Date(), -30));
return baseMapper.selectCount(wrapper);
}
}
diff --git a/im-admin/ruoyi-modules/ruoyi-system/pom.xml b/im-admin/ruoyi-modules/ruoyi-system/pom.xml
index bd391ab..127c892 100644
--- a/im-admin/ruoyi-modules/ruoyi-system/pom.xml
+++ b/im-admin/ruoyi-modules/ruoyi-system/pom.xml
@@ -90,11 +90,6 @@
ruoyi-common-websocket
-
- org.dromara
- ruoyi-common-sse
-
-
org.dromara
ruoyi-common-minio
diff --git a/im-admin/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java b/im-admin/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
index 5d65137..a0aa26e 100644
--- a/im-admin/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
+++ b/im-admin/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysNoticeController.java
@@ -8,8 +8,8 @@ import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
-import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.common.web.core.BaseController;
+import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.system.domain.bo.SysNoticeBo;
import org.dromara.system.domain.vo.SysNoticeVo;
import org.dromara.system.service.ISysNoticeService;
@@ -62,7 +62,7 @@ public class SysNoticeController extends BaseController {
return R.fail();
}
String type = dictService.getDictLabel("sys_notice_type", notice.getNoticeType());
- SseMessageUtils.publishAll("[" + type + "] " + notice.getNoticeTitle());
+ WebSocketUtils.publishAll("[" + type + "] " + notice.getNoticeTitle());
return R.ok();
}