没有@EnableWebSocketMessageBroker批注的Spring bean @Scope“ websocket”

Tit*_*ito 5 spring websocket spring-websocket

我有一个Spring Boot应用程序,它通过二进制websocket交换消息。即没有STOMP,AMQP等或任何其他消息传递协议!!!现在,我需要用“ websocket”的范围标记我的一个班级。像下面这样:

@Service("session")
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Session {
...
}
Run Code Online (Sandbox Code Playgroud)

我在这里阅读了 引用该文档的文档:

“可以将WebSocket范围的bean注入到控制器以及在“ clientInboundChannel”上注册的任何通道拦截器中。

我想在那句话中强调“和”一词。

好吧,我确实有一个控制器,但是我没有任何channelInterceptor。我将其注入为:

@Controller("entryPoint")
public class EntryPoint {
    @Autowired
    private ApplicationContext applicationContext;
    private ApplicationEventPublisher applicationEventPublisher;

    @Autowired
    private Session session;

    ...
    @PostConstruct
    public void init() {
        // Invoked after dependencies injected
        logger.info("EntryPoint init method i.e.  @PostConstruct invoked");

    }
...
}
Run Code Online (Sandbox Code Playgroud)

现在,我发现很有趣的第一个想法是,我需要注释@EnableWebSocketMessageBroker,即@EnableWebSocket似乎还不够,但是接着问为什么。无论我是否使用消息传递协议,我都应该能够独立定义该范围。至少那是我所相信的。

反正没有它我得到错误

java.lang.IllegalStateException: No Scope registered for scope name 'websocket'
Run Code Online (Sandbox Code Playgroud)

我说好,让我们为消息代理创建一个虚拟的配置文件,它带来了更多的依赖性,例如:

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
</dependency>

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-net</artifactId>
</dependency>

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.13.Final</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

作为一个像

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketMessageBrokerConfig  implements WebSocketMessageBrokerConfigurer {


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


    @Override
    public void configureClientInboundChannel(ChannelRegistration inboundChannelRegistration) {

    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration outboundChannelRegistration) {

    }

    @Override
    public boolean configureMessageConverters(List<MessageConverter> messageConverters) {

        return true;
    }

    @Override
    public void configureWebSocketTransport(WebSocketTransportRegistration webSocketTransportRegistration) {
        webSocketTransportRegistration.setMessageSizeLimit(45678910);
        webSocketTransportRegistration.setSendBufferSizeLimit(9101112);
        webSocketTransportRegistration.setSendTimeLimit(123456789);
    }



    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
        System.out.println("WEB SOCKET ARGUMENT RESOLVER");

    }


    @Override
    public void addReturnValueHandlers(
            List<HandlerMethodReturnValueHandler> arg0) {
        System.out.println("WEB SOCKET RETURN VALUE HANDLER");

    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {

        StompBrokerRelayRegistration stompBrokerRelayRegistration = config.enableStompBrokerRelay(
                                      "/topic/",
                                      "/queue/errors",                  
                                      "/exchange/amp.direct/testaError/",
                                      "/exchange/amp.direct/testCreateAccount/"
                                        );

        stompBrokerRelayRegistration.setRelayHost("127.0.0.6");
        stompBrokerRelayRegistration.setRelayPort(61613);
        stompBrokerRelayRegistration.setSystemLogin("guest");
        stompBrokerRelayRegistration.setSystemPasscode("guest");
        stompBrokerRelayRegistration.setAutoStartup(true);
        stompBrokerRelayRegistration.setSystemHeartbeatSendInterval(5000);
        stompBrokerRelayRegistration.setSystemHeartbeatReceiveInterval(4000);

        config.setApplicationDestinationPrefixes("/app");                               


    }



}
Run Code Online (Sandbox Code Playgroud)

带来错误信息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.serverSyncSession': Scope 'websocket' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound SimpAttributes found. Your code is probably not processing a client message and executing in message-handling methods invoked by the SimpAnnotationMethodMessageHandler?
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:355) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
...

Caused by: java.lang.IllegalStateException: No thread-bound SimpAttributes found. Your code is probably not processing a client message and executing in message-handling methods invoked by the SimpAnnotationMethodMessageHandler?
    at org.springframework.messaging.simp.SimpAttributesContextHolder.currentAttributes(SimpAttributesContextHolder.java:82) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.messaging.simp.SimpSessionScope.get(SimpSessionScope.java:36) ~[spring-messaging-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:340) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE]
    ... 45 common frames omitted
Run Code Online (Sandbox Code Playgroud)

虽然消息很清晰,即我的代码确实不是线程绑定的,并且不是在SimpAnnotationMethodMessageHandler中在messageHandelr中执行,而是在扩展BinaryWebSocketHandler的BinaryMessageHandler类中执行。为什么我不能在Websockets明确使用的bean上放置一个作用域。为什么我们需要所有注释@EnableWebSocketMessageBroker以及以下所有依赖项?

对我来说还不是很清楚,为了使豆具有正确的作用域,我还需要做什么。不知何故,我有种感觉,这将使我再次陷入某种我真正想避免的消息依赖。

我的问题是,有没有人对我有任何提示,我需要在BinaryMessageHandler中做些什么,以告诉spring将作用域为“ wesocket”的会话bean线程化。没有标注@EnableWebSocketMessageBroker,有没有办法做到这一点?

任何反馈表示赞赏。