Controller code:
@Controller
public class SockController {
@MessageMapping(value="/chat")
public void chatReveived(Message message, Principal principal) {
...
LOGGER.debug("chatReveived message [{}]", message);
...
}
}
WebSocketConfig:
@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))
With these code, the frontend is able to connect with server over WebSocket and send message. But @MessageMapping handler method chatReveived() doesn't get called.
frontend output:
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"}
server output:
[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
Seems like it is not able to find the handler method. Any idea where I was wrong?
My environment is: Tomcat 8.0.9, Spring 4.0.6 RELEASE, Spring security 3.2.4.RELEASE, JDK 7
WebSocketConfig configuration class should be loaded as part of Servlet configuration, not Root configuration.
Make sure WebSocketConfig.class
returned from your implementation of AbstractAnnotationConfigDispatcherServletInitializer.getRootConfigClasses()
If you put it in root context, everything will work fine, you can use SimpMessagingTemplate, broker relay, but not @MessageMapping in controllers.
You can set breakpoint in WebSocketAnnotationMethodMessageHandler.initControllerAdviceCache()
and check what beanss are loaded in context. If no @Controller
marked bean in that method, @MessageMapping
will not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With