I'm trying to understand how to publish/broadcast messages using websockets with Spring Boot to a Javascript application. All examples I can find are making use of a StompJs client - I however am unable to use StompJs in my client code, and I'm not sure my backend is correct which doesn't help.
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/subscribe")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
}
Just using a simple @Scheduled to produce the time every 5 seconds, and send it to the time topic (Well, I believe that's what it's doing...)
@Component
@Slf4j
public class TimeSender {
private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");
private SimpMessagingTemplate broker;
@Autowired
public TimeSender(final SimpMessagingTemplate broker) {
this.broker = broker;
}
@Scheduled(fixedRate = 5000)
public void run() {
String time = LocalTime.now().format(TIME_FORMAT);
log.info("Time broadcast: {}", time);
broker.convertAndSend("/topic/time", "Current time is " + time);
}
}
There are a few points I'm a little confused about when trying to test this. Using the Simple websocket client plugin for Chrome, I have to add websocket to the end of my request in order to connect. A connection would like ws://localhost:8080/subscribe/websocket Without the websocket I can't connect, but I can't find this mentioned in any examples or Spring documentation?
The second question is how do I subscribe to the time topic? All StompJs clients call something like client.subscribe("time") etc.
I've tried ws://localhost:8080/subscribe/topic/time/websocket but no luck in receiving any timestamps.
I'm not sure if my backend code is just wrong, my URL is wrong, or I'm just missing something else.
Note: My @Controller is missing from above as I'm just focused on pushing messages from Spring to clients at this stage, not receiving messages and It's my understanding controllers just deal with incoming?
-
Did you happen to resolve this? I am running into a similar problem.ccellist– ccellist2018年05月25日 14:09:16 +00:00Commented May 25, 2018 at 14:09
1 Answer 1
Well, I suppose if one searches obsessively enough the answer eventually turns up. Almost immediately after finding your post I found the answer I needed at http://www.marcelustrojahn.com/2016/08/spring-boot-websocket-example/. There is a really good example that essentially does what you are describing. The difference is they are using a Spring SimpMessagingTemplate to send messages to the queue. Once I followed his pattern, it all worked like a charm. Here is the relevant code snippet:
@Autowired
SimpMessagingTemplate template
@Scheduled(fixedDelay = 20000L)
@SendTo("/topic/pingpong")
public void sendPong() {
template.convertAndSend("/topic/pingpong", "pong (periodic)")
}
The method is void so the convertAndSend() method handles publishing to the topic, not the return statement as just about every other tutorial I've seen on the web indicates. This helped solve my problem.