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

时间:2017-07-10 19:10:28

标签: spring websocket spring-websocket

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

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

我已阅读引用的文档here

  

“WebSocket-scoped 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");

    }
...
}

现在我觉得有趣的第一个问题是我需要注释@EnableWebSocketMessageBroker,即似乎@EnableWebSocket是not enough,但接下来是问题原因。我应该能够无限制地定义该范围我是否使用消息传递协议。至少这是我所相信的。

无论如何没有它我得到错误

java.lang.IllegalStateException: No Scope registered for scope name 'websocket'

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

<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>

作为配置

@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");                               


    }



}

带来错误信息:

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

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

我真的不清楚我还需要做些什么才能让我的豆子具有合适的范围。不知怎的,我觉得这会让我再次遇到一些我真正想避免的消息依赖。

我的问题是,是否有人提示我在BinaryMessageHandler中需要做什么才能告诉spring将该会话bean与范围“wesocket”进行线程化。有没有办法在没有注释@EnableWebSocketMessageBroker的情况下实现这一目标?

任何反馈都表示赞赏。

0 个答案:

没有答案