shiro多端登录,同时接收消息

举报
林欣 发表于 2025/05/26 16:23:45 2025/05/26
【摘要】 在 Spring Boot 中结合 Shiro 实现同一个账号在多个终端(如电脑、手机、平板)上登录,并在接收消息时所有登录的终端都能收到消息,可以通过以下步骤实现: 1. 配置 Shiro 的会话管理首先,需要配置 Shiro 的会话管理器,以支持会话的共享和同步。可以使用 Shiro 的 DefaultWebSessionManager 并结合缓存技术(如 Redis)来实现会话的共享。...

在 Spring Boot 中结合 Shiro 实现同一个账号在多个终端(如电脑、手机、平板)上登录,并在接收消息时所有登录的终端都能收到消息,可以通过以下步骤实现:

1. 配置 Shiro 的会话管理

首先,需要配置 Shiro 的会话管理器,以支持会话的共享和同步。可以使用 Shiro 的 DefaultWebSessionManager 并结合缓存技术(如 Redis)来实现会话的共享。

配置示例

application.propertiesapplication.yml 中配置 Redis 作为会话存储:

# Redis 配置
spring.redis.host=localhost
spring.redis.port=6379

在 Shiro 配置类中配置会话管理器:

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.util.ThreadContext;

@Configuration
public class ShiroConfig {

    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setGlobalSessionTimeout(1800000); // 设置会话超时时间为 30 分钟
        sessionManager.setSessionDAO(redisSessionDAO()); // 使用 Redis 存储会话
        return sessionManager;
    }

    @Bean
    public EnterpriseCacheSessionDAO redisSessionDAO() {
        EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
        // 配置 Redis 连接,具体实现需要结合 Spring Data Redis
        // 这里假设已经配置了 RedisTemplate
        // sessionDAO.setRedisTemplate(redisTemplate);
        return sessionDAO;
    }

    @Bean
    public SecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setSessionManager(sessionManager());
        // 其他配置,如 Realm
        return securityManager;
    }

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        // 其他过滤器配置
        return shiroFilterFactoryBean;
    }

    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
}

2. 实现消息广播

为了实现所有登录终端都能接收到消息,可以使用 WebSocket 或其他消息推送技术(如 STOMP over WebSocket)来广播消息。

WebSocket 配置示例

在 Spring Boot 中配置 WebSocket 和 STOMP:

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }
}

消息控制器示例

创建一个控制器来处理消息的接收和广播:

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

@Controller
public class MessageController {

    @MessageMapping("/send/message")
    @SendTo("/topic/messages")
    public String broadcastMessage(String message) {
        return message;
    }
}

3. 前端实现

在前端,使用 WebSocket 客户端连接到服务器,并订阅消息主题:

const socket = new SockJS('/ws');
const stompClient = Stomp.over(socket);

stompClient.connect({}, function(frame) {
    console.log('Connected: ' + frame);
    stompClient.subscribe('/topic/messages', function(message) {
        console.log('Received message: ' + message.body);
        // 在这里处理接收到的消息
    });
});

function sendMessage() {
    const message = document.getElementById('message').value;
    stompClient.send("/app/send/message", {}, message);
}

4. 用户会话与消息关联

在用户登录时,确保每个会话都订阅了相同的消息主题。可以使用 Shiro 的会话对象来存储用户的订阅信息,以便在发送消息时,能够找到所有相关的会话。

总结

通过以上步骤,您可以在 Spring Boot 中结合 Shiro 实现同一个账号在多个终端上登录,并在接收消息时所有登录的终端都能收到消息。关键在于配置 Shiro 的会话管理以支持会话共享,并使用 WebSocket 或其他消息推送技术来实现消息的广播。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。