我有一个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的情况下实现这一目标?
任何反馈都表示赞赏。