Spring bean @Scope "websocket" without @EnableWebSocketMessageBroker annotation
I have a spring boot application that is messaging over a binary websocket. That is, NO STOMP, AMQP, etc. Or any other messaging protocol !!! Now I need to mark one of my classes with the "websocket" scope. Like this befow:
@Service("session")
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Session {
...
}
I read the documentation here which is quoted as saying:
"WebSocket-scoped beans can be injected into controllers and any channel interceptors registered with" clientInboundChannel "."
I would like to emphasize the word "and" in this sentence.
Well, I have a controller, but I don't have any channelInterceptor. I was injecting this like:
@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");
}
...
}
Now the first tiger I'm interested in is that I need the @EnableWebSocketMessageBroker annotation i.e. seems like @EnableWebSocket is not enough) but then the question is why, I should be able to define this scope regardless of whether I am using the messaging protocol or not. At least that's what I believe.
anyway without it I get the error
java.lang.IllegalStateException: No Scope registered for scope name 'websocket'
I said ok, let's create a dummy config file for the message broker that brings additional dependencies like:
<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>
as a configuration like
@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");
}
}
which outputs an error message:
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
So far the message is clear, that is, my code is really not thread bound and is executed in the Handelr message just not in the SimpAnnotationMethodMessageHandler, but in the BinaryMessageHandler class, which extends BinaryWebSocketHandler. Why can't I place the scope on the bean, it is explicitly used in websockets. Why is the @EnableWebSocketMessageBroker annotation needed in all and all of the following dependencies?
It's not entirely clear to me what else I need to do to get the bean with the correct scope. Somehow I get the feeling that this will again make me depend on some messages that I am really trying to avoid.
My question is, does anyone have a hint of me what I need to do in the BinaryMessageHandler in order to tell spring to thread this session bean scoped to "wesocket". Is there a way to achieve this without the @EnableWebSocketMessageBroker annotation?
any feedback is appreciated.
source to share
No one has answered this question yet
See similar questions:
or similar: