Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scheduled websocket push with Springboot

I want to create a simple news feed feature on the front end that will automatically update through websocket push notifications.

The technologies involved are:

  • Angular for the general front-end application
  • SockJS for creating websocket communication
  • Stomp over webosocket for receiving messages from a message broker
  • Springboot Websockets
  • Stomp Message Broker (the java related framework)

What I want to achieve on the front end is:

  1. Create a websocket connection when the view is loaded
  2. Create s stomp provider using that websocket
  3. Have my client subscribe to it
  4. Catch server pushed messages and update the angular view

As far as the server side code:

  1. Configure the websocket stuff and manage the connection
  2. Have the server push messages every X amount of time (through an executor or @Scheduled?).

I think I have achieved everything so far except the last part of the server side code. The example I was following uses the websocket in full duplex mode and when a client sends something then the server immediately responds to the message queue and all subscribed clients update. But what I want is for the server itself to send something over Stomp WITHOUT waiting for the client to make any requests.

At first I created a spring @Controller and added a method to it with @SendTo("/my/subscribed/path") annotation. However I have no idea how to trigger it. Also I tried adding @Scheduled but this annotation works only on methods with void return type (and I'm returning a NewsMessage object).

Essentially what I need is to have the client initialize a websocket connection, and after have the server start pushing messages through it at a set interval (or whenever an event is triggered it doesn't matter for now). Also, every new client should listen to the same message queue and receive the same messages.

like image 611
PentaKon Avatar asked May 18 '16 18:05

PentaKon


1 Answers

Before starting, make sure that you have the websocket dependencies in your pom.xml. For instance, the most important one:

<dependency>     <groupId>org.springframework</groupId>     <artifactId>spring-websocket</artifactId>     <version>${org.springframework-version}</version> </dependency> 

Then, you need to have your configuration in place. I suggest you start with simple broker.

@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {      @Override     public void registerStompEndpoints(StompEndpointRegistry registry) {         registry.addEndpoint("/portfolio").withSockJS();     }      @Override     public void configureMessageBroker(MessageBrokerRegistry config) {         config.setApplicationDestinationPrefixes("/app");         config.enableSimpleBroker("/topic", "/queue");     }  } 

Then your controller should look like this. When your AngularJs app opens a connection on /portfolio and sends a subscription to channel /topic/greeting, you will reach the controller and respond to all subscribed users.

@Controller public class GreetingController {          @MessageMapping("/greeting")     public String handle(String greeting) {         return "[" + getTimestamp() + ": " + greeting;     } } 

With regard to your scheduler question, you need to enable it via configuration:

@Configuration @EnableScheduling public class SchedulerConfig{} 

And then schedule it:

@Component public class ScheduledUpdatesOnTopic{      @Autowired     private SimpMessagingTemplate template;     @Autowired     private final MessagesSupplier messagesSupplier;      @Scheduled(fixedDelay=300)     public void publishUpdates(){         template.convertAndSend("/topic/greetings", messagesSupplier.get());     } } 

Hope this somehow clarified the concept and steps to be taken to make things work for you.

like image 111
RMachnik Avatar answered Sep 24 '22 01:09

RMachnik