我想配置一个Spring Boot Websocket消息代理,以便它按照提交的顺序分派消息。
基于answers to similar questions,我试图将调度任务执行程序的池大小设置为1,但是我仍然收到错误顺序的消息。
出于调试目的,我添加了发送前和发送后的通道拦截器,它们记录了在其上调度消息的线程,并且我可以看到线程ID有所不同。
我在做什么错了?
代码(科特琳):
Websocket配置:
package foo.bar
import org.slf4j.LoggerFactory
import org.springframework.context.annotation.Configuration
import org.springframework.messaging.Message
import org.springframework.messaging.MessageChannel
import org.springframework.messaging.simp.config.ChannelRegistration
import org.springframework.messaging.simp.config.MessageBrokerRegistry
import org.springframework.messaging.support.ChannelInterceptor
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker
import org.springframework.web.socket.config.annotation.StompEndpointRegistry
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer
@Configuration
@EnableWebSocketMessageBroker
class WebSocketConfig : WebSocketMessageBrokerConfigurer{
companion object {
private val LOGGER = LoggerFactory.getLogger(WebSocketConfig::class.java)
}
override fun configureMessageBroker(config: MessageBrokerRegistry) {
config.enableSimpleBroker("/topic")
config.setApplicationDestinationPrefixes("/app");
config.configureBrokerChannel().taskExecutor().corePoolSize(1)
config.configureBrokerChannel().taskExecutor().maxPoolSize(1)
val channelInterceptor: ChannelInterceptor = object: ChannelInterceptor {
override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
LOGGER.debug("Message broker sending message on Thread " + Thread.currentThread().id);
return message
}
override fun postSend(message: Message<*>, channel: MessageChannel, sent: Boolean) {
LOGGER.debug("Message broker sent message on Thread " + Thread.currentThread().id);
}
}
config.configureBrokerChannel().interceptors(channelInterceptor)
}
override fun registerStompEndpoints(registry: StompEndpointRegistry) {
registry.addEndpoint("/ws")
.withSockJS()
}
override fun configureClientOutboundChannel(registration: ChannelRegistration) {
registration.taskExecutor().corePoolSize(1)
registration.taskExecutor().maxPoolSize(1)
}
override fun configureClientInboundChannel(registration: ChannelRegistration) {
registration.taskExecutor().corePoolSize(1)
registration.taskExecutor().maxPoolSize(1)
}
}
(已剥离的)用于发送消息的代码:
@Controller
class StateController
@Autowired constructor(
private val template: SimpMessagingTemplate
) {
....
fun publishMsg(topicId: String, msg: MyMessageType){
template.convertAndSend("/topic/msg/"+topicId, msg)
}
}
这是一些示例记录。如您所见,执行程序正在使用多个Thread
,或者似乎有多个执行程序。另外,线程ID来回跳跃,对我来说,这似乎很清楚地证明派遣执行不如我期望的那样是单线程的。
记录:
09:48:12.257 DEBUG [ault-executor-4] channelInterceptor$1.preSend : 32 Message broker sending message on Thread 60
09:48:12.257 DEBUG [ault-executor-0] channelInterceptor$1.preSend : 32 Message broker sending message on Thread 47
09:48:12.257 DEBUG [ault-executor-0] channelInterceptor$1.postSend : 38 Message broker sent message on Thread 47
09:48:12.257 DEBUG [ault-executor-4] channelInterceptor$1.postSend : 38 Message broker sent message on Thread 60
答案 0 :(得分:0)
进一步调试后,我发现了我的错误。不同的线程来自提交代码。我应该将通道拦截器添加到出站客户端通道,而不是代理:
override fun configureClientOutboundChannel(registration: ChannelRegistration) {
val channelInterceptor: ChannelInterceptor = object: ChannelInterceptor {
override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
LOGGER.debug("Message broker sending message on Thread " + Thread.currentThread().id);
return message
}
override fun postSend(message: Message<*>, channel: MessageChannel, sent: Boolean) {
LOGGER.debug("Message broker sent message on Thread " + Thread.currentThread().id);
}
}
registration.interceptors(channelInterceptor)
}