【问题标题】:SimpUserRegistry doesnot contain any session objectsSimpUserRegistry 不包含任何会话对象
【发布时间】:2021-07-31 22:14:09
【问题描述】:

我是 Websockets 新手。我一直在尝试使用 SimpUserRegistry 通过 Principal 查找会话对象。我编写了一个自定义握手处理程序来将匿名用户转换为经过身份验证的用户,并且我能够从 Websocket 会话对象访问主体名称。

自定义握手处理程序的代码如下所示


import java.security.Principal;

public class StompPrincipal implements Principal {
    private String name;

    public StompPrincipal(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
}

处理程序

class CustomHandshakeHandlerTwo extends DefaultHandshakeHandler {
    // Custom class for storing principal
    @Override
    protected Principal determineUser(
            ServerHttpRequest request,
            WebSocketHandler wsHandler,
            Map<String, Object> attributes
    ) {
        // Generate principal with UUID as name
        return new StompPrincipal(UUID.randomUUID().toString());
    }
}

但正如this 等许多问题中所述,我无法直接注入SimpUserRegistry

报错


Field simpUserRegistry  required a bean of type 'org.springframework.messaging.simp.user.SimpUserRegistry' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'org.springframework.messaging.simp.user.SimpUserRegistry' in your configuration.


所以我创建了一个如下所示的配置类。


@Configuration
public class UsersConfig {
    final private SimpUserRegistry userRegistry = new DefaultSimpUserRegistry();

    @Bean
    @Primary
    public SimpUserRegistry userRegistry() {
        return userRegistry;
    }
}

现在我可以自动连接并使用它,但每次我尝试访问 SimpUserRegistry 时它都是空的。

这个问题的原因可能是什么?

编辑:

显示 websocket 配置

@Configuration
@EnableWebSocket
@Controller
@Slf4j
public class WebSocketConfig implements WebSocketConfigurer {
    
    @Autowired
    EventTextHandler2 handler;
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        log.info("Registering websocket handler SocketTextHandler");
        registry.addHandler(handler, "/event").setHandshakeHandler(new CustomHandshakeHandlerTwo());
    }
}

【问题讨论】:

    标签: java spring-boot websocket


    【解决方案1】:

    SimpUserRegistry 是 Spring WebSocket 注册/提供的“基础设施 bean”,你不应该直接实例化它。

    你的 WebSocket Spring 配置正确吗?

    1. 确保您的应用程序配置正确(即正在扫描您的配置类)。

    SimpUserRegistryspring-messaging 依赖项导入:确保您的配置类使用@EnableWebSocketMessageBroker 进行注释。

    官方文档:https://docs.spring.io/spring-framework/docs/5.3.6/reference/html/web.html#websocket-stomp-enable

    1. 要在 Redis 中支持已连接的用户,您可能需要创建一个新的 SimpUserRegistry 实现:
    public class RedisSimpUserRegistry implements SimpUserRegistry, SmartApplicationListener {
    
      private final RedisTemplate redisTemplate;
    
      public RedisSimpUserRegistry(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
      }
    
      [...]
    
      @Override
      public void onApplicationEvent(ApplicationEvent event) {
        // Maintain Redis collection on event type
        // ie. SessionConnectedEvent / SessionDisconnectEvent
      }
      [...]
    }
    

    PS:除非您在其中定义了端点,否则您的配置类上的 @Controller 注释不是必需的。

    在新 cmets 之后编辑:

    您可以查看DefaultSimpUserRegistry 实现以了解如何操作。

    要拦截应用程序事件,您必须实现ApplicationListener 接口(在本例中为SmartApplicationListener)。 supportsEventType 方法对于定义要拦截的事件类型很重要:

      @Override
      public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return AbstractSubProtocolEvent.class.isAssignableFrom(eventType);
      }
    

    AbstractSubProtocolEvent 有多个实现。最重要的是SessionConnectEventSessionDisconnectEvent

    拦截(参见onApplicationEvent 方法)这些事件类型将允许您的实现在 Redis 缓存中保持所需的状态。然后您可以存储用户(ID 等)。

    【讨论】:

    • 我已经实现了 websocket 配置器并将代码添加到问题中。你能看一下吗。
    • 有没有办法将这些存储在redis缓存中。
    • 您能否详细说明在 onApplicationEvent 中要做什么。它会自动检测 bean 创建等事件吗?我应该使用 CRUDRepository 将数据添加到 redis 集合吗?如何访问 websocket 对象,我应该从 websocketHandler 的 afterConnectionEstablished 方法中获取它吗?我一直在做一些研究,它说 websocket 会话不可序列化,因此将其添加到 redis 是一个问题。
    • 如果您能说出您对这些的想法,那将非常有帮助。
    • 你能不能也看看这个问题。该apporach与跺脚。 stackoverflow.com/questions/67501308/….
    猜你喜欢
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 2011-01-20
    相关资源
    最近更新 更多