代码之家  ›  专栏  ›  技术社区  ›  instantaphex

spring stomp over websocket subscribebemapping不工作

  •  0
  • instantaphex  · 技术社区  · 6 年前

    我正在尝试在一个spring boot应用程序中为stomp over 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方法从未被调用。有什么明显的我遗漏了吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   rieckpil    6 年前

    请尝试以下操作:

    @Controller
    class TestController {
    
        @SubscribeMapping("/test")
        fun testMapping(): String {
            return "THIS IS A TEST"
        }
    }