Spring 4 WebSocket + sockJS:在跟踪中得到“找不到匹配的方法”并且@MessageMapping处理程序未被调用。

7

控制器代码:

@Controller
public class SockController {

    @MessageMapping(value="/chat")
    public void chatReveived(Message message, Principal principal) {
        ...
        LOGGER.debug("chatReveived message [{}]", message);
        ...  
    }
}

WebSocket配置:

@Configuration
@EnableWebSocketMessageBroker
@EnableScheduling
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/queue/", "/topic/");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/portfolio").withSockJS();
    }
}

Javascript:

        var socket = new SockJS('/portfolio');
        var stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            ...
        });
        stompClient.send("/app/chat", {}, JSON.stringify(message))

使用这些代码,前端可以通过WebSocket连接到服务器并发送消息。但是@MessageMapping处理程序方法chatReveived()没有被调用。
前端输出:
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.1,1.0
heart-beat:10000,10000

<<< CONNECTED
user-name:1
heart-beat:0,0
version:1.1

>>> SEND
destination:/app/chat
content-length:35

{"from":{"userId":1},"text":"ssss"}

服务器输出:

[21:19:26.551] TRACE org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator: TextMessage payload= SEND
desti.., byteCount=82, last=true], SockJsSession[id=mdibjok1, state=OPEN, sinceCreated=8504, sinceLastActive=8504]
 - 
[21:19:26.551] DEBUG org.springframework.messaging.simp.stomp.StompDecoder: Decoded [Payload byte[35]][Headers={stompCommand=SEND, nativeHeaders={content-length=[35], destination=[/app/chat]}, simpMessageType=MESSAGE, simpDestination=/app/chat, id=b7f01f0b-db3e-911d-60dc-c7275f8ef306, timestamp=1407201566551}]
 - 
[21:19:26.551] TRACE org.springframework.web.socket.messaging.StompSubProtocolHandler: Received message from client session=mdibjok1
 - 
[21:19:26.551] TRACE org.springframework.messaging.support.ExecutorSubscribableChannel: [clientInboundChannel] sending message id=0f482da7-fee0-d8f1-4b47-bd993eaee80d
 - 
[21:19:26.551] TRACE org.springframework.messaging.support.ChannelInterceptorChain: postSend (sent=true) message id 0f482da7-fee0-d8f1-4b47-bd993eaee80d
 - 
[21:19:26.552] DEBUG org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler: Handling message, lookupDestination=/chat
 - 
[21:19:26.553] DEBUG org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler: No matching method found
 - 
[21:19:26.553] TRACE org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler: Ignoring message to destination=/app/chat
 - 
[21:19:26.554] TRACE org.springframework.messaging.simp.user.DefaultUserDestinationResolver: Ignoring message to /app/chat, not a "user" destination

似乎无法找到处理程序方法。 有任何想法我错在哪里了吗?

我的环境是:Tomcat 8.0.9,Spring 4.0.6 RELEASE,Spring security 3.2.4.RELEASE,JDK 7


我有一个非常类似的问题,你找到根本原因了吗?看起来我的JSON没有与方法的参数匹配,而该参数是我发送的JSON字符串的POJO。如果你找到了问题,请告诉我 :) - a.hrdie
2个回答

4

WebSocketConfig配置类应该作为Servlet配置的一部分进行加载,而不是根配置。

确保从AbstractAnnotationConfigDispatcherServletInitializer.getRootConfigClasses()返回你的实现中的WebSocketConfig.class

如果将其放在根上下文中,一切都将正常工作,您可以使用SimpMessagingTemplate、代理中继,但不能在控制器中使用@MessageMapping。

您可以在WebSocketAnnotationMethodMessageHandler.initControllerAdviceCache()中设置断点,并检查在上下文中加载了哪些bean。如果在该方法中没有标记为@Controller的bean,则@MessageMapping将无法工作。


2
确保你的代码中使用了@Controller注解,而不是@Service - Dmitry Zlykh
兄弟,6年后你仍然帮助人们摆脱因为沮丧而拔头发的困扰。这真是个好办法。谢谢! - SnowmanXL

0
尝试在WebSocketConfig中使用@ComponentScan,这样Spring就可以找到Controller。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接