Hello and thanks in advance if you'll have time to read and maybe answer to my question.
I have an already working SpringBoot 3.2.4 app that is communicating with an Angular client via websocket configured with the typical approach using Stomp. This app is deployed in a Kubernetes cluster and now we need to have the minimum instances of the pod set to two, scaling up caused the websocket stop to working. I'm trying to configure the websocket connection using Spring Data Redis in order to dispatch the message to all the instances.
Why Redis? Because is already configured for the cache and would be great to use it also for this purpouse instead of adding other complexity to maintain.
I followed this guide here.
Everything is ok and it's working because I can start up multiple instances and all of the instances are receiving the message arrived to the first pod, so I can assume that Redis is properly configured on server side.
This is my publisher
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class RedisMessagePublisher implements MessagePublisher {
private final RedisTemplate<String, Object> redisTemplate;
@Override
public void publish(String topic, String message) {
redisTemplate.convertAndSend(topic, message);
}
public RedisMessagePublisher(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
and this is my listener
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class RedisMessageSubscriber implements MessageListener {
public static final List<String> messageList = new ArrayList<>();
@Override
public void onMessage(Message message, byte[] pattern) {
messageList.add(message.toString());
log.info("message received: {}", new String(message.getBody()));
}
}
My problem is that the client is an angular app that is hosted directly by the SpringBoot application. This means that each instance has his own client.
The question is how I should configure the Angular app in order to receive and read the message from the websocket?
I still need to create a configuration class with @EnableWebSocketMessageBroker and register the stomp endpoint in order to let the Angular app to register to the websocket?
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Slf4j
@Configuration
@EnableWebSocketMessageBroker
public class ConfigurationWebSocketBroker implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket")
.setAllowedOriginPatterns("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
Is this possible to achieve, or Redis in my case is not the correct solution?