๐ฟ๐ฆ ์ค์๊ฐ ์ฑํ ์๋น์ค๋ฅผ ์ํ SrpingBoot REST API
- Spring Boot 2.1.5.RELEASE
- Java 1.8
- spring-boot-starter-websocket
- spring-kafka
- guava
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chatting").setAllowedOrigins("*").withSockJS();
}
}
- configureMessageBroker : Message Broker์ ๋ํ ์ค์ ์ ์งํํ๋ ๋ฉ์๋์ด๋ค.
- enableSimpleBroke : ํ๋ผ๋ฏธํฐ๋ก ๋ฃ์ด ์ค ๊ฒฝ๋ก๋ก Simple Broker๋ฅผ ๋ฑ๋กํ๋ค. Simple Broker๋ ํด๋น ๊ฒฝ๋ก๋ฅผ Subscribeํ๋ ํด๋ผ์ด์ธํธ์๊ฒ ๋ฉ์์ง๋ฅผ ์ ๋ฌํ๋ ์์ ์ ์ํํ๋ค.
- setApplicationDestinationPrefixes : ํด๋ผ์ด์ธํธ์์์ send ์์ฒญ์ ์ฒ๋ฆฌ, ๋ง์ฝ topic/hello ํ ํฝ์ ๋ํด ๊ตฌ๋ ์ ์ฒญ์, ์ค์ ๊ฒฝ๋ก๋ /app/topic/hello ๊ฐ ๋๋ค.
- registerStompEndpoints : handshake์ ํต์ ์ ๋ด๋นํ endpoint๋ฅผ ์ง์ ํ๋ค.๋ํ setAllowedOrigins(*)๋ฅผ ํตํด ์น์์ผ ํต์ ์ด ์์ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์์ ์ด ์๋๋๋ผ๋ ํต์ ์ด ๊ฐ๋ฅ ํ ์ ์๊ฒ ํด์ค๋ค. ์๋ฅผ ๋ค์ด http://localhost:8080/stomp ๋ก ์น์์ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋๋ฐ (์ค์ ์์ ) http://localhost ๋ก ์น์์ผ ํต์ ์ ์๋ํ๋ฉด (์์ฒญ์์ ) connect ์ด ์ด๋ค์ง์ง ์๋๋ค. ์ ํํ ํฌํธ๋ฒํธ๊น์ง ์ผ์นํด์ผ ํ๋ค. ๋ฐ๋ผ์ ์ค์ ๋ ๋๋ฉ์ธ ์ธ์ ์ฐ๊ฒฐ์ ํ์ฉํ ๋๋ฉ์ธ์ ์ง์ ํด์ค์ผ๋ก์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค. ๋จ ์์ผ ๊ฐ์ฒด๋ฅผ ์ฐ๊ฒฐํ ๋๋ฉ์ธ์์๋ง ์ฑํ ์ด ์ด๋ฃจ์ด์ง๋ค๋ฉด ํ์ํ์ง ์๋ค.
@Service
public class Receiver {
private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
@Autowired
private SimpMessagingTemplate template;
@KafkaListener(id = "main-listener", topics = "kafka-chatting")
public void receive(ChattingMessage message) throws Exception{
LOGGER.info("message='{}'", message);
HashMap<String, String> msg = new HashMap<>();
msg.put("timestamp", Long.toString(message.getTimeStamp()));
msg.put("message", message.getMessage());
msg.put("author", message.getUser());
ObjectMapper mapper = new ObjectMapper(); // ์ ์ฐ๋๊ฑฐ์ง?
String json = mapper.writeValueAsString(msg);
this.template.convertAndSend("/topic/public", json);
}
}
- ChattingMessage๋ฅผ HashMap์ผ๋ก ๋ฐ๊พธ๊ณ , ์ด๋ฅผ Jackson ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ Object mapper๋ฅผ ํตํด JSON ํํ๋ก ๋ณํํ๋ค. ์ด๋ฅผ SimpMessagingTemplated์ ํตํด /topic/public์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ธ๋ค.
@Component
public class ChattingHistoryDAO {
private final Cache<UUID, ChattingMessage> chatHistoryCache = CacheBuilder
.newBuilder().maximumSize(20).expireAfterWrite(10, TimeUnit.MINUTES)
.build();
public void save(ChattingMessage chatObj){
this.chatHistoryCache.put(UUID.randomUUID(), chatObj);
}
public List<ChattingMessage> get(){
return chatHistoryCache.asMap().values().stream()
.sorted(Comparator.comparing(ChattingMessage::getTimeStamp))
.collect(Collectors.toList());
}
}
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋์ guava์์ ์ ๊ณตํ๋ ์บ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ์์ง๋ฅผ ์ ์ฅํ๋ค.
https://dydtjr1128.github.io/spring/2019/05/26/Springboot-react-chatting.html