feat : rabbitmq 추가 완료

This commit is contained in:
yulmam 2024-07-31 12:52:40 +09:00
parent c94827259f
commit b9cc9b8a50
8 changed files with 186 additions and 98 deletions

View File

@ -0,0 +1,13 @@
package com.edufocus.edufocus.global.config;
import com.edufocus.edufocus.global.properties.RabbitMQProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties({
RabbitMQProperties.class
})
public class PropertiesConfig {
}

View File

@ -0,0 +1,15 @@
package com.edufocus.edufocus.global.constant;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum RabbitMQConstant {
CHAT_QUEUE_NAME("chat.queue"),
CHAT_EXCHANGE("chat.exchange"),
ROUTING_KEY("*.room.*"),
ROUTING_KEY_PREFIX("*.room.");;
private final String constant;
}

View File

@ -0,0 +1,16 @@
package com.edufocus.edufocus.global.properties;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Getter
@RequiredArgsConstructor
@ConfigurationProperties(prefix = "spring.rabbitmq")
public class RabbitMQProperties {
private final String host;
private final Integer port;
private final String username;
private final String password;
}

View File

@ -14,39 +14,38 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@EnableWebMvc @EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer { public class WebConfiguration implements WebMvcConfigurer {
// private JWTInterceptor jwtInterceptor; private JWTInterceptor jwtInterceptor;
//
// public WebConfiguration(JWTInterceptor jwtInterceptor) { public WebConfiguration(JWTInterceptor jwtInterceptor) {
// super(); super();
//
// this.jwtInterceptor = jwtInterceptor; this.jwtInterceptor = jwtInterceptor;
// } }
//
// @Override @Override
// public void addCorsMappings(CorsRegistry registry) { public void addCorsMappings(CorsRegistry registry) {
// registry registry
// .addMapping("/**") .addMapping("/**")
// .allowedOrigins("http://i11a701.p.ssafy.io/", "http://localhost:5173", "http://localhost:4173") .allowedOrigins("http://i11a701.p.ssafy.io/", "http://localhost:5173", "http://localhost:4173")
// .allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(), .allowedMethods(HttpMethod.GET.name(), HttpMethod.POST.name(), HttpMethod.PUT.name(),
// HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name(), HttpMethod.DELETE.name(), HttpMethod.HEAD.name(), HttpMethod.OPTIONS.name(),
// HttpMethod.PATCH.name()) HttpMethod.PATCH.name())
// .allowCredentials(true) .allowCredentials(true)
// .allowedHeaders("*") .allowedHeaders("*")
// .maxAge(1800); // Pre-flight Caching .maxAge(1800); // Pre-flight Caching
// } }
//
// @Override @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/assets/img/"); registry.addResourceHandler("/img/**").addResourceLocations("classpath:/static/assets/img/");
// registry.addResourceHandler("/*.html**").addResourceLocations("classpath:/static/"); registry.addResourceHandler("/*.html**").addResourceLocations("classpath:/static/");
// } }
// @Override @Override
// public void addInterceptors(InterceptorRegistry registry) { public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(jwtInterceptor) registry.addInterceptor(jwtInterceptor)
// .addPathPatterns("/**") // 모든 경로에 대해 인터셉터 적용
// .addPathPatterns("/**") // 모든 경로에 대해 인터셉터 적용 .excludePathPatterns("/v3/api-docs/**","/swagger-resources/**","/webjars/**","/swagger-ui/**","/auth/**", "/board/**", "/user/**","/lecture/**","/qna/**", "/quiz/**"); // 인증 없이 접근 가능한 경로 설정
// .excludePathPatterns("/v3/api-docs/**","/swagger-resources/**","/webjars/**","/swagger-ui/**","/auth/**", "/board/**", "/user/**","/lecture/**","/qna/**", "/quiz/**"); // 인증 없이 접근 가능한 경로 설정
// ///v3/api-docs/**, /swagger-resources/**, /webjars/**
// ///v3/api-docs/**, /swagger-resources/**, /webjars/** }
// }
} }

View File

@ -1,2 +1,73 @@
package com.edufocus.edufocus.ws.config;public class RabbitConfig { package com.edufocus.edufocus.ws.config;
import com.edufocus.edufocus.global.constant.RabbitMQConstant;
import com.edufocus.edufocus.global.properties.RabbitMQProperties;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitConfig {
private final RabbitMQProperties rabbitMQProperties;
public RabbitConfig(RabbitMQProperties rabbitMQProperties) {
this.rabbitMQProperties = rabbitMQProperties;
}
@Bean
public Queue queue() {
return new Queue(RabbitMQConstant.CHAT_QUEUE_NAME.getConstant(), true);
}
@Bean
public TopicExchange exchange() {
return new TopicExchange(RabbitMQConstant.CHAT_EXCHANGE.getConstant());
}
@Bean
Binding binding(TopicExchange topicExchange, Queue queue) {
return BindingBuilder.bind(queue).to(topicExchange).with(RabbitMQConstant.ROUTING_KEY.getConstant());
}
@Bean
ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setHost(rabbitMQProperties.getHost());
connectionFactory.setPort(rabbitMQProperties.getPort());
connectionFactory.setUsername(rabbitMQProperties.getUsername());
connectionFactory.setPassword(rabbitMQProperties.getPassword());
return connectionFactory;
}
@Bean
public AmqpAdmin amqpAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());
rabbitAdmin.declareQueue(queue());
return rabbitAdmin;
}
@Bean
MessageConverter messageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter);
return rabbitTemplate;
}
} }

View File

@ -1,7 +1,9 @@
package com.edufocus.edufocus.ws.config; package com.edufocus.edufocus.ws.config;
import com.edufocus.edufocus.global.properties.RabbitMQProperties;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@ -10,15 +12,23 @@ import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerCo
@EnableWebSocketMessageBroker @EnableWebSocketMessageBroker
public class WebSocketConfigurer implements WebSocketMessageBrokerConfigurer { public class WebSocketConfigurer implements WebSocketMessageBrokerConfigurer {
private final RabbitMQProperties rabbitMQProperties;
public WebSocketConfigurer(RabbitMQProperties rabbitMQProperties) {
this.rabbitMQProperties = rabbitMQProperties;
}
@Override @Override
public void configureMessageBroker(MessageBrokerRegistry registry) { public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setPathMatcher(new AntPathMatcher("."));
registry.setApplicationDestinationPrefixes("/pub") registry.setApplicationDestinationPrefixes("/pub")
.enableStompBrokerRelay("/topic") .enableStompBrokerRelay("/topic", "/queue", "/exchange")
.setRelayHost("localhost") .setRelayHost(rabbitMQProperties.getHost())
.setVirtualHost("/") .setVirtualHost("/")
.setRelayPort(61613) .setRelayPort(61613)
.setClientLogin("guest") .setClientLogin(rabbitMQProperties.getUsername())
.setClientPasscode("guest"); .setClientPasscode(rabbitMQProperties.getPassword());
} }
@Override @Override

View File

@ -1,11 +1,13 @@
package com.edufocus.edufocus.ws.controller; package com.edufocus.edufocus.ws.controller;
import com.edufocus.edufocus.global.constant.RabbitMQConstant;
import com.edufocus.edufocus.user.util.JWTUtil; import com.edufocus.edufocus.user.util.JWTUtil;
import com.edufocus.edufocus.ws.entity.dto.MessageDto; import com.edufocus.edufocus.ws.entity.dto.MessageDto;
import com.edufocus.edufocus.ws.entity.dto.QuizDto; import com.edufocus.edufocus.ws.entity.dto.QuizDto;
import com.edufocus.edufocus.ws.entity.dto.ChatUserDto; import com.edufocus.edufocus.ws.entity.dto.ChatUserDto;
import com.edufocus.edufocus.ws.service.ChatService; import com.edufocus.edufocus.ws.service.ChatService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
@ -30,70 +32,26 @@ import java.util.List;
@RestController @RestController
public class ChatController { public class ChatController {
private final SimpMessageSendingOperations simpMessageSendingOperations; RabbitTemplate rabbitTemplate;
private final ChatService chatService; public ChatController(RabbitTemplate rabbitTemplate){
this.rabbitTemplate = rabbitTemplate;
private final JWTUtil jwtUtil;
public ChatController(SimpMessageSendingOperations simpMessageSendingOperations, ChatService chatService, JWTUtil jwtUtil){
this.simpMessageSendingOperations = simpMessageSendingOperations;
this.chatService = chatService;
this.jwtUtil = jwtUtil;
} }
@GetMapping("/chat/enter/{lectureId}") @MessageMapping("chat.message.{lectureId}")
public ResponseEntity<?> enter(@PathVariable long lectureId){ public void sendMessage(@DestinationVariable long lectureId, MessageDto messageDto){
List<ChatUserDto> chatUsers = chatService.findChatUsers(lectureId); rabbitTemplate.convertAndSend(RabbitMQConstant.CHAT_EXCHANGE.getConstant(),
RabbitMQConstant.ROUTING_KEY_PREFIX.getConstant() + lectureId,
messageDto);
}
return new ResponseEntity<>(chatUsers, HttpStatus.OK); @MessageMapping("chat.quiz.{lectureId}")
public void quizStart(@DestinationVariable long lectureId, QuizDto quizDto){
rabbitTemplate.convertAndSend(RabbitMQConstant.CHAT_EXCHANGE.getConstant(),
RabbitMQConstant.ROUTING_KEY_PREFIX.getConstant() + lectureId,
quizDto);
} }
@MessageMapping("/hello/{channelId}")
@SendTo("/topic/{channelId}")
public ChatUserDto hello(@DestinationVariable long channelId, SimpMessageHeaderAccessor simpMessageHeaderAccessor, @Header("Authorization") String token){
String sessionId = simpMessageHeaderAccessor.getSessionId();
System.out.println("session" + sessionId);
System.out.println("가냐?????"+token);
long userId = Long.parseLong(jwtUtil.getUserId(token));
chatService.saveChatUserInfo(userId, channelId, sessionId);
return chatService.getChatUserInfo(userId);
}
@MessageMapping("/message/{lectureId}")
@SendTo("/topic/{lectureId}")
public MessageDto sendMessage(@DestinationVariable long lectureId, MessageDto messageDto){return messageDto;}
@MessageMapping("/quiz/{lectureId}")
@SendTo("/topic/{lectureId}")
public QuizDto quizStart(@DestinationVariable long lectureId, QuizDto quizDto){
return quizDto;
}
// @EventListener
// public void handleWebSocketDisconnectListener(SessionDisconnectEvent event){
// StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
// String sessionId = headerAccessor.getSessionId();
//
//
// ChatUserDto chatUserDto = chatService.getChatUserInfo(sessionId);
//
//
// if(chatService.checkTeacher(chatUserDto)){
// chatService.closeChatRoom(chatUserDto.getLectureId());
// simpMessageSendingOperations.convertAndSend("/sub/channel/" + chatUserDto.getLectureId(), "강의가 종료 됐습니다.");
// return;
// }
//
// chatService.deleteChatUserInfo(chatUserDto.getUserId());
// simpMessageSendingOperations.convertAndSend("/sub/channel/" + chatUserDto.getLectureId(), chatUserDto);
// }
} }

View File

@ -37,3 +37,9 @@ spring.mail.password=mnlyfkiprltjlsmw
spring.mail.properties.mail.smtp.auth=true spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true spring.mail.properties.mail.smtp.starttls.enable=true
spring.rabbitmq.host=${RABBITMQ_HOST}
spring.rabbitmq.port=${RABBITMQ_PORT}
spring.rabbitmq.username=${RABBITMQ_USERNAME}
spring.rabbitmq.password=${RABBITMQ_PASSWORD}