Spring 踩过 websocket SubscribeMapping 不工作
Spring stomp over websocket SubscribeMapping not working
我正在尝试配置订阅映射,以便在 spring 引导应用程序中踩踏 websockets,但没有任何运气。我相当确定我已经正确配置了 stomp/websocket 东西,因为我能够订阅由 kafka 消费者发布的主题,但是使用 @SubscribeMapping 根本不起作用。
这是我的控制器
@Controller
class TestController {
@SubscribeMapping("/topic/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}
这是我的配置
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
class WebSocketConfig : AbstractWebSocketMessageBrokerConfigurer() {
override fun configureMessageBroker(config: MessageBrokerRegistry) {
config.setApplicationDestinationPrefixes("/app", "/topic")
config.enableSimpleBroker("/queue", "/topic")
config.setUserDestinationPrefix("/user")
}
override fun registerStompEndpoints(registry:StompEndpointRegistry) {
registry.addEndpoint("/ws").setAllowedOrigins("*")
}
override fun configureClientInboundChannel(registration: ChannelRegistration?) {
registration?.setInterceptors(object: ChannelInterceptorAdapter() {
override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
val accessor: StompHeaderAccessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor::class.java)
if (StompCommand.CONNECT.equals(accessor.command)) {
Optional.ofNullable(accessor.getNativeHeader("authorization")).ifPresent {
val token = it[0]
val keyReader = KeyReader()
val creds = Jwts.parser().setSigningKey(keyReader.key).parseClaimsJws(token).body
val groups = creds.get("groups", List::class.java)
val authorities = groups.map { SimpleGrantedAuthority(it as String) }
val authResult = UsernamePasswordAuthenticationToken(creds.subject, token, authorities)
SecurityContextHolder.getContext().authentication = authResult
accessor.user = authResult
}
}
return message
}
})
}
}
然后在 UI 代码中,我使用 angular 和 stompjs 包装器来订阅它,如下所示:
this.stompService.subscribe('/topic/test')
.map(data => data.body)
.subscribe(data => console.log(data));
像这样订阅我知道正在发送数据的主题非常有效,但订阅映射什么也不做。我还尝试在我的 websocket 配置中添加一个事件侦听器,以测试 UI 是否真的像这样向后端发送订阅事件:
@EventListener
fun handleSubscribeEvent(event: SessionSubscribeEvent) {
println("Subscription event: $event")
}
@EventListener
fun handleConnectEvent(event: SessionConnectEvent) {
println("Connection event: $event")
}
@EventListener
fun handleDisconnectEvent(event: SessionDisconnectEvent) {
println("Disconnection event: $event")
}
添加这些事件侦听器我可以看到我期望来自 UI 的所有事件都在 kotlin 层中通过,但我的控制器方法从未被调用。有什么明显的我遗漏的吗?
尝试以下操作:
@Controller
class TestController {
@SubscribeMapping("/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}
我正在尝试配置订阅映射,以便在 spring 引导应用程序中踩踏 websockets,但没有任何运气。我相当确定我已经正确配置了 stomp/websocket 东西,因为我能够订阅由 kafka 消费者发布的主题,但是使用 @SubscribeMapping 根本不起作用。
这是我的控制器
@Controller
class TestController {
@SubscribeMapping("/topic/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}
这是我的配置
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
class WebSocketConfig : AbstractWebSocketMessageBrokerConfigurer() {
override fun configureMessageBroker(config: MessageBrokerRegistry) {
config.setApplicationDestinationPrefixes("/app", "/topic")
config.enableSimpleBroker("/queue", "/topic")
config.setUserDestinationPrefix("/user")
}
override fun registerStompEndpoints(registry:StompEndpointRegistry) {
registry.addEndpoint("/ws").setAllowedOrigins("*")
}
override fun configureClientInboundChannel(registration: ChannelRegistration?) {
registration?.setInterceptors(object: ChannelInterceptorAdapter() {
override fun preSend(message: Message<*>, channel: MessageChannel): Message<*> {
val accessor: StompHeaderAccessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor::class.java)
if (StompCommand.CONNECT.equals(accessor.command)) {
Optional.ofNullable(accessor.getNativeHeader("authorization")).ifPresent {
val token = it[0]
val keyReader = KeyReader()
val creds = Jwts.parser().setSigningKey(keyReader.key).parseClaimsJws(token).body
val groups = creds.get("groups", List::class.java)
val authorities = groups.map { SimpleGrantedAuthority(it as String) }
val authResult = UsernamePasswordAuthenticationToken(creds.subject, token, authorities)
SecurityContextHolder.getContext().authentication = authResult
accessor.user = authResult
}
}
return message
}
})
}
}
然后在 UI 代码中,我使用 angular 和 stompjs 包装器来订阅它,如下所示:
this.stompService.subscribe('/topic/test')
.map(data => data.body)
.subscribe(data => console.log(data));
像这样订阅我知道正在发送数据的主题非常有效,但订阅映射什么也不做。我还尝试在我的 websocket 配置中添加一个事件侦听器,以测试 UI 是否真的像这样向后端发送订阅事件:
@EventListener
fun handleSubscribeEvent(event: SessionSubscribeEvent) {
println("Subscription event: $event")
}
@EventListener
fun handleConnectEvent(event: SessionConnectEvent) {
println("Connection event: $event")
}
@EventListener
fun handleDisconnectEvent(event: SessionDisconnectEvent) {
println("Disconnection event: $event")
}
添加这些事件侦听器我可以看到我期望来自 UI 的所有事件都在 kotlin 层中通过,但我的控制器方法从未被调用。有什么明显的我遗漏的吗?
尝试以下操作:
@Controller
class TestController {
@SubscribeMapping("/test")
fun testMapping(): String {
return "THIS IS A TEST"
}
}