I am going through the websockets with Spring 4 tutorial here. I have it working where the server responds when client calls.
However, my use case is having the server push the messages without client having to call. So I looked up online on ways to do that and came across a few posts that said that I needed to use something called SimpMessagingTemplate
.
So I changed the code to use the SimpMessagingTemplate
.
Now I get this exception in the server console:
04-Jun-2016 22:49:24.093 SEVERE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.springframework.web.context.ContextLoader.initWebApplicationContext Context initialization failed
org.springframework.context.ApplicationContextException: Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:176)
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:346)
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:149)
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:112)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:852)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4809)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5251)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3827)
at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:291)
at org.apache.catalina.core.StandardContext.backgroundProcess(StandardContext.java:5608)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1377)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1381)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1381)
at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1349)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: No handlers
at org.springframework.util.Assert.isTrue(Assert.java:68)
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler.start(SubProtocolWebSocketHandler.java:251)
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:173)
... 20 more
I found this post and this post with the same issue but none of them have a real solution posted.
My websocket controller:
@Controller
public class WebSockController {
private SimpMessagingTemplate template;
@Autowired
public WebSockController(SimpMessagingTemplate template) {
this.template = template;
}
@MessageMapping("/hello")
public void greeting(GreetingsFromClient message) throws Exception {
String[] messages = {"message1","message2","message3","message4","message5"};
for(int i=0 ; i<messages.length ; i++){
Thread.sleep(3000); // simulated delay
this.template.convertAndSend("/topic/greetings", new GreetingsFromServer("Hello, " + messages[i] + "!"));
}
}
}
My websocket config:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/hello").withSockJS();
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureClientInboundChannel(ChannelRegistration arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureClientOutboundChannel(ChannelRegistration arg0) {
// TODO Auto-generated method stub
}
@Override
public boolean configureMessageConverters(List<MessageConverter> arg0) {
// TODO Auto-generated method stub
return true;
}
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration arg0) {
// TODO Auto-generated method stub
}
}
Also I had to add org.springframework.web.socket.config
to component scan because without this I would get an auto-wiring exception (ref).
I am using Spring 4.2.5 and Tomcat 8.
Any help is appreciated. Please let me know if you need more info. Thanks.
After struggling with this problem for a few hours, I resolved this by adding the websocket config to the rootconfig.
My application initializer that uses the root config.