From 509764bc50fa45f12c3c6075fc295414cb6ca9dd Mon Sep 17 00:00:00 2001 From: luke Date: Sat, 18 May 2024 15:23:59 +0900 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20websocket=20=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=EB=B8=8C=EB=9F=AC=EB=A6=AC=20=EC=B6=94=EA=B0=80(#76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- be/build.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/be/build.gradle b/be/build.gradle index 9d01f983..177ddf86 100644 --- a/be/build.gradle +++ b/be/build.gradle @@ -52,6 +52,11 @@ dependencies { // fcm implementation 'com.google.firebase:firebase-admin:9.2.0' + + // websocket + implementation 'org.springframework.boot:spring-boot-starter-websocket' + implementation 'org.webjars:stomp-websocket:2.3.3-1' + implementation 'org.webjars:sockjs-client:1.1.2' } tasks.named('bootBuildImage') { From f390f42f5afe529b7c299171e7a02f12693fd74f Mon Sep 17 00:00:00 2001 From: luke Date: Sat, 18 May 2024 15:28:46 +0900 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20socket=20config=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- be/build.gradle | 3 ++ .../yeonba/be/config/WebSocketConfig.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 be/src/main/java/yeonba/be/config/WebSocketConfig.java diff --git a/be/build.gradle b/be/build.gradle index 177ddf86..b4b4a7ff 100644 --- a/be/build.gradle +++ b/be/build.gradle @@ -57,6 +57,9 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-websocket' implementation 'org.webjars:stomp-websocket:2.3.3-1' implementation 'org.webjars:sockjs-client:1.1.2' + + // redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' } tasks.named('bootBuildImage') { diff --git a/be/src/main/java/yeonba/be/config/WebSocketConfig.java b/be/src/main/java/yeonba/be/config/WebSocketConfig.java new file mode 100644 index 00000000..3c078245 --- /dev/null +++ b/be/src/main/java/yeonba/be/config/WebSocketConfig.java @@ -0,0 +1,30 @@ +package yeonba.be.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +@Configuration +@EnableWebSocket +@RequiredArgsConstructor +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void configureMessageBroker(MessageBrokerRegistry config) { + + config.enableSimpleBroker("/chat/sub"); + config.setApplicationDestinationPrefixes("/chat/pub"); + } + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + + registry.addEndpoint("/chat") + .withSockJS(); + } +} From 7e7cb36937093197dbfb5768feac7fe7bef23bb1 Mon Sep 17 00:00:00 2001 From: luke Date: Tue, 21 May 2024 18:52:04 +0900 Subject: [PATCH 3/7] =?UTF-8?q?feat:=20redis=20pub/sub=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EA=B5=AC=ED=98=84(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ingController.java => ChatController.java} | 20 +++++- .../dto/request/ChatPublishRequest.java | 15 ++++ .../dto/request/ChatSubscribeResponse.java | 15 ++++ .../request/ChattingSendMessageRequest.java | 17 ----- .../chatmessage/ChatMessageCommand.java | 2 +- .../chatroom/ChatMessageCommand.java | 17 +++++ .../chatroom/ChatMessageRepository.java | 8 +++ .../repository/chatroom/ChatRoomQuery.java | 6 ++ .../be/chatting/service/ChatService.java | 22 +++++- .../service/RedisChattingPublisher.java | 19 +++++ .../service/RedisChattingSubscriber.java | 40 +++++++++++ .../java/yeonba/be/config/RedisConfig.java | 71 +++++++++++++++++++ 12 files changed, 229 insertions(+), 23 deletions(-) rename be/src/main/java/yeonba/be/chatting/controller/{ChattingController.java => ChatController.java} (82%) create mode 100644 be/src/main/java/yeonba/be/chatting/dto/request/ChatPublishRequest.java create mode 100644 be/src/main/java/yeonba/be/chatting/dto/request/ChatSubscribeResponse.java delete mode 100644 be/src/main/java/yeonba/be/chatting/dto/request/ChattingSendMessageRequest.java create mode 100644 be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java create mode 100644 be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java create mode 100644 be/src/main/java/yeonba/be/chatting/service/RedisChattingPublisher.java create mode 100644 be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java create mode 100644 be/src/main/java/yeonba/be/config/RedisConfig.java diff --git a/be/src/main/java/yeonba/be/chatting/controller/ChattingController.java b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java similarity index 82% rename from be/src/main/java/yeonba/be/chatting/controller/ChattingController.java rename to be/src/main/java/yeonba/be/chatting/controller/ChatController.java index cb15645e..8111fc71 100644 --- a/be/src/main/java/yeonba/be/chatting/controller/ChattingController.java +++ b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java @@ -7,24 +7,36 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestAttribute; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.ResponseBody; +import yeonba.be.chatting.dto.request.ChatPublishRequest; import yeonba.be.chatting.dto.response.ChatRoomResponse; import yeonba.be.chatting.service.ChatService; +import yeonba.be.chatting.service.RedisChattingPublisher; import yeonba.be.util.CustomResponse; @Tag(name = "Chatting", description = "채팅 API") -@RestController +@Controller @RequiredArgsConstructor -public class ChattingController { +public class ChatController { private final ChatService chatService; + private final RedisChattingPublisher redisChattingPublisher; + + @MessageMapping("/chat") + public void chat(ChatPublishRequest request) { + + chatService.publish(request); + } @Operation(summary = "채팅 목록 조회", description = "자신이 참여 중인 채팅 목록을 조회할 수 있습니다.") @ApiResponse(responseCode = "200", description = "참여 중인 채팅 목록 조회 성공") + @ResponseBody @GetMapping("/chattings") public ResponseEntity>> getChatRooms( @RequestAttribute("userId") long userId) { @@ -38,6 +50,7 @@ public ResponseEntity>> getChatRooms( @Operation(summary = "채팅 요청", description = "다른 사용자에게 채팅을 요청할 수 있습니다.") @ApiResponse(responseCode = "200", description = "채팅 요청 정상 처리") + @ResponseBody @PostMapping("/users/{partnerId}/chat") public ResponseEntity> requestChat( @RequestAttribute("userId") long userId, @@ -53,6 +66,7 @@ public ResponseEntity> requestChat( @Operation(summary = "채팅 요청 수락", description = "요청받은 채팅을 수락할 수 있습니다.") @ApiResponse(responseCode = "200", description = "채팅 요청 수락 정상 처리") + @ResponseBody @PostMapping("/notifications/{notificationId}/chat") public ResponseEntity> acceptRequestedChat( @RequestAttribute("userId") long userId, diff --git a/be/src/main/java/yeonba/be/chatting/dto/request/ChatPublishRequest.java b/be/src/main/java/yeonba/be/chatting/dto/request/ChatPublishRequest.java new file mode 100644 index 00000000..ade1c49e --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/dto/request/ChatPublishRequest.java @@ -0,0 +1,15 @@ +package yeonba.be.chatting.dto.request; + +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; + +@Getter +public class ChatPublishRequest implements Serializable { + + private long roomId; + private long userId; + private String userName; + private String content; + private LocalDateTime sentAt; +} diff --git a/be/src/main/java/yeonba/be/chatting/dto/request/ChatSubscribeResponse.java b/be/src/main/java/yeonba/be/chatting/dto/request/ChatSubscribeResponse.java new file mode 100644 index 00000000..6e734bd4 --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/dto/request/ChatSubscribeResponse.java @@ -0,0 +1,15 @@ +package yeonba.be.chatting.dto.request; + +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.Getter; + +@Getter +public class ChatSubscribeResponse implements Serializable { + + private long roomId; + private long userId; + private String userName; + private String content; + private LocalDateTime sentAt; +} diff --git a/be/src/main/java/yeonba/be/chatting/dto/request/ChattingSendMessageRequest.java b/be/src/main/java/yeonba/be/chatting/dto/request/ChattingSendMessageRequest.java deleted file mode 100644 index 56fc2c85..00000000 --- a/be/src/main/java/yeonba/be/chatting/dto/request/ChattingSendMessageRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package yeonba.be.chatting.dto.request; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public class ChattingSendMessageRequest { - - @Schema( - type = "string", - description = "메시지 내용", - example = "밥 먹었어?" - ) - private String content; -} diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageCommand.java b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageCommand.java index c7a9e5ae..f9137e37 100644 --- a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageCommand.java +++ b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageCommand.java @@ -10,7 +10,7 @@ public class ChatMessageCommand { private final ChatMessageRepository chatMessageRepository; - public ChatMessage createChatMessage(ChatMessage message) { + public ChatMessage save(ChatMessage message) { return chatMessageRepository.save(message); } diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java new file mode 100644 index 00000000..b6a51390 --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java @@ -0,0 +1,17 @@ +package yeonba.be.chatting.repository.chatroom; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import yeonba.be.chatting.entity.ChatMessage; + +@Component +@RequiredArgsConstructor +public class ChatMessageCommand { + + private final ChatMessageRepository chatMessageRepository; + + public ChatMessage save(ChatMessage chatMessage) { + + return chatMessageRepository.save(chatMessage); + } +} diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java new file mode 100644 index 00000000..1fe0ebd1 --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java @@ -0,0 +1,8 @@ +package yeonba.be.chatting.repository.chatroom; + +import org.springframework.data.jpa.repository.JpaRepository; +import yeonba.be.chatting.entity.ChatMessage; + +public interface ChatMessageRepository extends JpaRepository { + +} diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatRoomQuery.java b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatRoomQuery.java index 01915f92..681b0339 100644 --- a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatRoomQuery.java +++ b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatRoomQuery.java @@ -15,6 +15,12 @@ public class ChatRoomQuery { private final ChatRoomRepository chatRoomRepository; + public ChatRoom findById(long id) { + + return chatRoomRepository.findById(id) + .orElseThrow(() -> new GeneralException(NOT_FOUND_CHAT_ROOM)); + } + public List findAllBy(User user) { return chatRoomRepository.findAllByUserAndActiveIsTrue(user); diff --git a/be/src/main/java/yeonba/be/chatting/service/ChatService.java b/be/src/main/java/yeonba/be/chatting/service/ChatService.java index 078d52fc..5cfc0d28 100644 --- a/be/src/main/java/yeonba/be/chatting/service/ChatService.java +++ b/be/src/main/java/yeonba/be/chatting/service/ChatService.java @@ -5,8 +5,10 @@ import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import yeonba.be.chatting.dto.request.ChatPublishRequest; import yeonba.be.chatting.dto.response.ChatRoomResponse; import yeonba.be.chatting.entity.ChatMessage; import yeonba.be.chatting.entity.ChatRoom; @@ -39,6 +41,20 @@ public class ChatService { private final NotificationQuery notificationQuey; private final ApplicationEventPublisher eventPublisher; + private final RedisChattingPublisher redisChattingPublisher; + + @Transactional + public void publish(ChatPublishRequest request) { + + ChatRoom chatRoom = chatRoomQuery.findById(request.getRoomId()); + User sender = userQuery.findById(request.getUserId()); + User receiver = chatRoom.getSender().equals(sender) ? chatRoom.getReceiver() + : chatRoom.getSender(); + + // TODO: 메시지 Pub/Sub과 메시지 저장 로직 비동기 처리(id, user 등 request, response 변경 가능) + redisChattingPublisher.publish(new ChannelTopic(String.valueOf(request.getRoomId())), request); + chatMessageCommand.save(new ChatMessage(chatRoom, sender, receiver, request.getContent())); + } @Transactional(readOnly = true) public List getChatRooms(long userId) { @@ -105,7 +121,8 @@ public void acceptRequestedChat(long userId, long notificationId) { // 본인에게 온 채팅 요청인지 검증 if (receiver.equals(userQuery.findById(userId))) { - throw new GeneralException(NotificationException.NOT_YOUR_CHATTING_REQUEST_NOTIFICATION); + throw new GeneralException( + NotificationException.NOT_YOUR_CHATTING_REQUEST_NOTIFICATION); } // 채팅방 활성화 @@ -113,7 +130,8 @@ public void acceptRequestedChat(long userId, long notificationId) { chatRoom.activeRoom(); String activeRoom = "채팅방이 활성화되었습니다."; - chatMessageCommand.createChatMessage(new ChatMessage(chatRoom, sender, receiver, activeRoom)); + chatMessageCommand.save( + new ChatMessage(chatRoom, sender, receiver, activeRoom)); NotificationSendEvent notificationSendEvent = new NotificationSendEvent( NotificationType.CHATTING_REQUEST_ACCEPTED, receiver, sender, diff --git a/be/src/main/java/yeonba/be/chatting/service/RedisChattingPublisher.java b/be/src/main/java/yeonba/be/chatting/service/RedisChattingPublisher.java new file mode 100644 index 00000000..60a525c2 --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/service/RedisChattingPublisher.java @@ -0,0 +1,19 @@ +package yeonba.be.chatting.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.stereotype.Service; +import yeonba.be.chatting.dto.request.ChatPublishRequest; + +@Service +@RequiredArgsConstructor +public class RedisChattingPublisher { + + private final RedisTemplate redisTemplate; + + public void publish(ChannelTopic topic, ChatPublishRequest request) { + + redisTemplate.convertAndSend(topic.getTopic(), request); + } +} diff --git a/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java b/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java new file mode 100644 index 00000000..100af3f9 --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java @@ -0,0 +1,40 @@ +package yeonba.be.chatting.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.connection.Message; +import org.springframework.data.redis.connection.MessageListener; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.messaging.simp.SimpMessageSendingOperations; +import org.springframework.stereotype.Service; +import yeonba.be.chatting.dto.request.ChatSubscribeResponse; + +@Slf4j +@Service +@RequiredArgsConstructor +public class RedisChattingSubscriber implements MessageListener { + + private final ObjectMapper objectMapper; + private final RedisTemplate redisTemplate; + private final SimpMessageSendingOperations messagingTemplate; + + @Override + public void onMessage(Message message, byte[] pattern) { + + try { + + // redis에서 발행된 데이터를 받아 deserialize + String publishedMessage = (String) redisTemplate.getStringSerializer() + .deserialize(message.getBody()); + + // ChatMessage 객채로 맵핑 + ChatSubscribeResponse response = objectMapper.readValue(publishedMessage, ChatSubscribeResponse.class); + + // Websocket 구독자에게 채팅 메시지 Send + messagingTemplate.convertAndSend("/chat/sub/room" + response.getRoomId(), response); + } catch (Exception e) { + log.error(e.getMessage()); + } + } +} diff --git a/be/src/main/java/yeonba/be/config/RedisConfig.java b/be/src/main/java/yeonba/be/config/RedisConfig.java new file mode 100644 index 00000000..fdf2b584 --- /dev/null +++ b/be/src/main/java/yeonba/be/config/RedisConfig.java @@ -0,0 +1,71 @@ +package yeonba.be.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; +import yeonba.be.chatting.service.RedisChattingSubscriber; + +@Configuration +@RequiredArgsConstructor +public class RedisConfig { + + private final ObjectMapper objectMapper; + + /** + * redis pub/sub 메시지 처리 listender 설정 + */ + @Bean + public RedisMessageListenerContainer redisMessageListenerContainer( + RedisConnectionFactory connectionFactory, + MessageListenerAdapter adapter, + ChannelTopic topic) { + + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(connectionFactory); + container.addMessageListener(adapter, topic); + return container; + } + + /** + * 어플리케이션에서 사용할 redisTemplate 설정 + */ + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(connectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)); + return redisTemplate; + } + + @Bean + public RedisTemplate stringIntegerRedisTemplate(RedisConnectionFactory connectionFactory) { + + var redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(connectionFactory); + + return redisTemplate; + } + + @Bean + public MessageListenerAdapter messageListenerAdapter(RedisChattingSubscriber subscriber) { + + return new MessageListenerAdapter(subscriber, "onMessage"); + } + + @Bean + public ChannelTopic channelTopic() { + + return new ChannelTopic("global"); + } +} From dab29857e213be68a2f0cc4460a10783f3b14abb Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 22 May 2024 16:42:40 +0900 Subject: [PATCH 4/7] =?UTF-8?q?feat:=20=EC=B1=84=ED=8C=85=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatting/controller/ChatController.java | 30 ++++++++++++++++--- .../dto/response/ChatMessageResponse.java | 21 +++++++++++++ .../be/chatting/entity/ChatMessage.java | 3 +- .../chatroom/ChatMessageCommand.java | 17 ----------- .../chatroom/ChatMessageRepository.java | 8 ----- .../be/chatting/service/ChatService.java | 13 ++++++-- .../service/RedisChattingSubscriber.java | 4 ++- .../java/yeonba/be/config/RedisConfig.java | 12 +------- .../java/yeonba/be/config/SwaggerConfig.java | 2 +- be/src/main/resources/application.yml | 9 +++++- 10 files changed, 72 insertions(+), 47 deletions(-) create mode 100644 be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java delete mode 100644 be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java delete mode 100644 be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java diff --git a/be/src/main/java/yeonba/be/chatting/controller/ChatController.java b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java index 8111fc71..653a6505 100644 --- a/be/src/main/java/yeonba/be/chatting/controller/ChatController.java +++ b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java @@ -5,7 +5,13 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import java.util.List; +import java.util.Set; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.http.ResponseEntity; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.stereotype.Controller; @@ -15,29 +21,45 @@ import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.ResponseBody; import yeonba.be.chatting.dto.request.ChatPublishRequest; +import yeonba.be.chatting.dto.response.ChatMessageResponse; import yeonba.be.chatting.dto.response.ChatRoomResponse; import yeonba.be.chatting.service.ChatService; -import yeonba.be.chatting.service.RedisChattingPublisher; import yeonba.be.util.CustomResponse; @Tag(name = "Chatting", description = "채팅 API") +@Slf4j @Controller @RequiredArgsConstructor public class ChatController { private final ChatService chatService; - private final RedisChattingPublisher redisChattingPublisher; @MessageMapping("/chat") public void chat(ChatPublishRequest request) { + log.info("chatting test log {}", request.getContent()); + chatService.publish(request); } - @Operation(summary = "채팅 목록 조회", description = "자신이 참여 중인 채팅 목록을 조회할 수 있습니다.") + @Operation(summary = "채팅 메시지 목록 조회", description = "특정 채팅방의 메시지 목록을 조회할 수 있습니다.") + @ApiResponse(responseCode = "200", description = "채팅 메시지 목록 조회 성공") + @ResponseBody + @GetMapping("/chat-rooms/{roomId}/messages") + public ResponseEntity>> getChatMessages( + @RequestAttribute("userId") long userId, + @Parameter(description = "채팅방 ID", example = "1") + @PathVariable long roomId) { + + return ResponseEntity + .ok() + .body(new CustomResponse<>(null)); + } + + @Operation(summary = "채팅방 목록 조회", description = "자신이 참여 중인 채팅 목록을 조회할 수 있습니다.") @ApiResponse(responseCode = "200", description = "참여 중인 채팅 목록 조회 성공") @ResponseBody - @GetMapping("/chattings") + @GetMapping("/chat-rooms") public ResponseEntity>> getChatRooms( @RequestAttribute("userId") long userId) { diff --git a/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java b/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java new file mode 100644 index 00000000..4ba865af --- /dev/null +++ b/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java @@ -0,0 +1,21 @@ +package yeonba.be.chatting.dto.response; + +import java.time.LocalDateTime; +import lombok.Getter; + +@Getter +public class ChatMessageResponse { + + private long userId; + private String userName; + private String content; + private LocalDateTime sentAt; + + public ChatMessageResponse(long userId, String userName, String content, LocalDateTime sentAt) { + + this.userId = userId; + this.userName = userName; + this.content = content; + this.sentAt = sentAt; + } +} diff --git a/be/src/main/java/yeonba/be/chatting/entity/ChatMessage.java b/be/src/main/java/yeonba/be/chatting/entity/ChatMessage.java index 33ba4dfb..3f4a2e7a 100644 --- a/be/src/main/java/yeonba/be/chatting/entity/ChatMessage.java +++ b/be/src/main/java/yeonba/be/chatting/entity/ChatMessage.java @@ -53,12 +53,13 @@ public class ChatMessage { private LocalDateTime deletedAt; - public ChatMessage(ChatRoom chatRoom, User sender, User receiver, String content) { + public ChatMessage(ChatRoom chatRoom, User sender, User receiver, String content, LocalDateTime sentAt) { this.chatRoom = chatRoom; this.sender = sender; this.receiver = receiver; this.content = content; + this.sentAt = sentAt; this.read = false; } } diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java deleted file mode 100644 index b6a51390..00000000 --- a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageCommand.java +++ /dev/null @@ -1,17 +0,0 @@ -package yeonba.be.chatting.repository.chatroom; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Component; -import yeonba.be.chatting.entity.ChatMessage; - -@Component -@RequiredArgsConstructor -public class ChatMessageCommand { - - private final ChatMessageRepository chatMessageRepository; - - public ChatMessage save(ChatMessage chatMessage) { - - return chatMessageRepository.save(chatMessage); - } -} diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java b/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java deleted file mode 100644 index 1fe0ebd1..00000000 --- a/be/src/main/java/yeonba/be/chatting/repository/chatroom/ChatMessageRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package yeonba.be.chatting.repository.chatroom; - -import org.springframework.data.jpa.repository.JpaRepository; -import yeonba.be.chatting.entity.ChatMessage; - -public interface ChatMessageRepository extends JpaRepository { - -} diff --git a/be/src/main/java/yeonba/be/chatting/service/ChatService.java b/be/src/main/java/yeonba/be/chatting/service/ChatService.java index 5cfc0d28..18901b27 100644 --- a/be/src/main/java/yeonba/be/chatting/service/ChatService.java +++ b/be/src/main/java/yeonba/be/chatting/service/ChatService.java @@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import yeonba.be.chatting.dto.request.ChatPublishRequest; @@ -42,6 +43,8 @@ public class ChatService { private final ApplicationEventPublisher eventPublisher; private final RedisChattingPublisher redisChattingPublisher; + private final RedisChattingSubscriber adapter; + private final RedisMessageListenerContainer container; @Transactional public void publish(ChatPublishRequest request) { @@ -53,7 +56,7 @@ public void publish(ChatPublishRequest request) { // TODO: 메시지 Pub/Sub과 메시지 저장 로직 비동기 처리(id, user 등 request, response 변경 가능) redisChattingPublisher.publish(new ChannelTopic(String.valueOf(request.getRoomId())), request); - chatMessageCommand.save(new ChatMessage(chatRoom, sender, receiver, request.getContent())); + chatMessageCommand.save(new ChatMessage(chatRoom, sender, receiver, request.getContent(), request.getSentAt())); } @Transactional(readOnly = true) @@ -129,9 +132,13 @@ public void acceptRequestedChat(long userId, long notificationId) { ChatRoom chatRoom = chatRoomQuery.findBy(sender, receiver); chatRoom.activeRoom(); - String activeRoom = "채팅방이 활성화되었습니다."; + String activeRoom = "채팅방이 생성되었습니다."; + chatMessageCommand.save( - new ChatMessage(chatRoom, sender, receiver, activeRoom)); + new ChatMessage(chatRoom, sender, receiver, activeRoom, LocalDateTime.now())); + + // 메시지 수신을 위한 Redis Pub/Sub 구독 + container.addMessageListener(adapter, new ChannelTopic(String.valueOf(chatRoom.getId()))); NotificationSendEvent notificationSendEvent = new NotificationSendEvent( NotificationType.CHATTING_REQUEST_ACCEPTED, receiver, sender, diff --git a/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java b/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java index 100af3f9..515159ff 100644 --- a/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java +++ b/be/src/main/java/yeonba/be/chatting/service/RedisChattingSubscriber.java @@ -31,8 +31,10 @@ public void onMessage(Message message, byte[] pattern) { // ChatMessage 객채로 맵핑 ChatSubscribeResponse response = objectMapper.readValue(publishedMessage, ChatSubscribeResponse.class); + log.info("Chatting message received: {}", response.getContent()); + // Websocket 구독자에게 채팅 메시지 Send - messagingTemplate.convertAndSend("/chat/sub/room" + response.getRoomId(), response); + messagingTemplate.convertAndSend("/chat/sub/room/" + response.getRoomId(), response); } catch (Exception e) { log.error(e.getMessage()); } diff --git a/be/src/main/java/yeonba/be/config/RedisConfig.java b/be/src/main/java/yeonba/be/config/RedisConfig.java index fdf2b584..0d1d250c 100644 --- a/be/src/main/java/yeonba/be/config/RedisConfig.java +++ b/be/src/main/java/yeonba/be/config/RedisConfig.java @@ -10,7 +10,6 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; -import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import yeonba.be.chatting.service.RedisChattingSubscriber; @@ -25,13 +24,10 @@ public class RedisConfig { */ @Bean public RedisMessageListenerContainer redisMessageListenerContainer( - RedisConnectionFactory connectionFactory, - MessageListenerAdapter adapter, - ChannelTopic topic) { + RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); - container.addMessageListener(adapter, topic); return container; } @@ -62,10 +58,4 @@ public MessageListenerAdapter messageListenerAdapter(RedisChattingSubscriber sub return new MessageListenerAdapter(subscriber, "onMessage"); } - - @Bean - public ChannelTopic channelTopic() { - - return new ChannelTopic("global"); - } } diff --git a/be/src/main/java/yeonba/be/config/SwaggerConfig.java b/be/src/main/java/yeonba/be/config/SwaggerConfig.java index 61badca7..80fbb810 100644 --- a/be/src/main/java/yeonba/be/config/SwaggerConfig.java +++ b/be/src/main/java/yeonba/be/config/SwaggerConfig.java @@ -21,7 +21,7 @@ public OpenAPI customOpenAPI() { return new OpenAPI() .components(new Components()) - .addServersItem(new Server().url("https://api.yeonba.co.kr")) +// .addServersItem(new Server().url("https://api.yeonba.co.kr")) .info(info); } diff --git a/be/src/main/resources/application.yml b/be/src/main/resources/application.yml index e8db33a9..e048178f 100644 --- a/be/src/main/resources/application.yml +++ b/be/src/main/resources/application.yml @@ -12,4 +12,11 @@ spring: properties: hibernate: show_sql: false - format_sql: false \ No newline at end of file + format_sql: false + + data: + redis: + host: ${REDIS_HOST} + port: ${REDIS_PORT} + password: ${REDIS_PASSWORD} + timeout: 60000 From b221a0673e0867ec73fcfb38f3f6adf9222a1d41 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 22 May 2024 16:51:19 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chatting/controller/ChatController.java | 4 ++- .../chatmessage/ChatMessageQuery.java | 7 +++++ .../chatmessage/ChatMessageRepository.java | 4 +++ .../be/chatting/service/ChatService.java | 29 +++++++++++++++++-- .../yeonba/be/exception/ChatException.java | 4 +++ 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/be/src/main/java/yeonba/be/chatting/controller/ChatController.java b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java index 653a6505..4d4ffeec 100644 --- a/be/src/main/java/yeonba/be/chatting/controller/ChatController.java +++ b/be/src/main/java/yeonba/be/chatting/controller/ChatController.java @@ -51,9 +51,11 @@ public ResponseEntity>> getChatMessages @Parameter(description = "채팅방 ID", example = "1") @PathVariable long roomId) { + List response = chatService.getChatMessages(userId, roomId); + return ResponseEntity .ok() - .body(new CustomResponse<>(null)); + .body(new CustomResponse<>(response)); } @Operation(summary = "채팅방 목록 조회", description = "자신이 참여 중인 채팅 목록을 조회할 수 있습니다.") diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageQuery.java b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageQuery.java index 1ea9beb4..ac9ddaf7 100644 --- a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageQuery.java +++ b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageQuery.java @@ -1,8 +1,10 @@ package yeonba.be.chatting.repository.chatmessage; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import yeonba.be.chatting.entity.ChatMessage; +import yeonba.be.chatting.entity.ChatRoom; @Component @RequiredArgsConstructor @@ -19,4 +21,9 @@ public int countUnreadMessagesByChatRoomId(long chatRoomId) { return chatMessageRepository.countByChatRoomIdAndReadIsFalse(chatRoomId); } + + public List findAllByChatRoom(ChatRoom chatRoom) { + + return chatMessageRepository.findAllByChatRoomOrderBySentAtDesc(chatRoom); + } } diff --git a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageRepository.java b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageRepository.java index 0205b255..4bcc60a3 100644 --- a/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageRepository.java +++ b/be/src/main/java/yeonba/be/chatting/repository/chatmessage/ChatMessageRepository.java @@ -1,8 +1,10 @@ package yeonba.be.chatting.repository.chatmessage; +import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import yeonba.be.chatting.entity.ChatMessage; +import yeonba.be.chatting.entity.ChatRoom; @Repository public interface ChatMessageRepository extends JpaRepository { @@ -10,4 +12,6 @@ public interface ChatMessageRepository extends JpaRepository ChatMessage findFirstByChatRoomIdOrderBySentAtDesc(long chatRoomId); int countByChatRoomIdAndReadIsFalse(long chatRoomId); + + List findAllByChatRoomOrderBySentAtDesc(ChatRoom chatRoom); } diff --git a/be/src/main/java/yeonba/be/chatting/service/ChatService.java b/be/src/main/java/yeonba/be/chatting/service/ChatService.java index 18901b27..2993d931 100644 --- a/be/src/main/java/yeonba/be/chatting/service/ChatService.java +++ b/be/src/main/java/yeonba/be/chatting/service/ChatService.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import yeonba.be.chatting.dto.request.ChatPublishRequest; +import yeonba.be.chatting.dto.response.ChatMessageResponse; import yeonba.be.chatting.dto.response.ChatRoomResponse; import yeonba.be.chatting.entity.ChatMessage; import yeonba.be.chatting.entity.ChatRoom; @@ -17,7 +18,9 @@ import yeonba.be.chatting.repository.chatmessage.ChatMessageQuery; import yeonba.be.chatting.repository.chatroom.ChatRoomCommand; import yeonba.be.chatting.repository.chatroom.ChatRoomQuery; +import yeonba.be.chatting.repository.chatroom.ChatRoomRepository; import yeonba.be.exception.BlockException; +import yeonba.be.exception.ChatException; import yeonba.be.exception.GeneralException; import yeonba.be.exception.NotificationException; import yeonba.be.notification.entity.Notification; @@ -45,6 +48,7 @@ public class ChatService { private final RedisChattingPublisher redisChattingPublisher; private final RedisChattingSubscriber adapter; private final RedisMessageListenerContainer container; + private final ChatRoomRepository chatRoomRepository; @Transactional public void publish(ChatPublishRequest request) { @@ -55,8 +59,29 @@ public void publish(ChatPublishRequest request) { : chatRoom.getSender(); // TODO: 메시지 Pub/Sub과 메시지 저장 로직 비동기 처리(id, user 등 request, response 변경 가능) - redisChattingPublisher.publish(new ChannelTopic(String.valueOf(request.getRoomId())), request); - chatMessageCommand.save(new ChatMessage(chatRoom, sender, receiver, request.getContent(), request.getSentAt())); + redisChattingPublisher.publish(new ChannelTopic(String.valueOf(request.getRoomId())), + request); + chatMessageCommand.save( + new ChatMessage(chatRoom, sender, receiver, request.getContent(), request.getSentAt())); + } + + public List getChatMessages(long userId, long roomId) { + + User user = userQuery.findById(userId); + + ChatRoom chatRoom = chatRoomQuery.findById(roomId); + + if (!user.equals(chatRoom.getSender()) && !user.equals(chatRoom.getReceiver())) { + throw new GeneralException(ChatException.NOT_YOUR_CHAT_ROOM); + } + + List chatMessages = chatMessageQuery.findAllByChatRoom(chatRoom); + + return chatMessages.stream() + .map(chatMessage -> new ChatMessageResponse(chatMessage.getSender().getId(), + chatMessage.getSender().getNickname(), + chatMessage.getContent(), chatMessage.getSentAt())) + .toList(); } @Transactional(readOnly = true) diff --git a/be/src/main/java/yeonba/be/exception/ChatException.java b/be/src/main/java/yeonba/be/exception/ChatException.java index f1df029b..3bb5783b 100644 --- a/be/src/main/java/yeonba/be/exception/ChatException.java +++ b/be/src/main/java/yeonba/be/exception/ChatException.java @@ -4,6 +4,10 @@ public enum ChatException implements BaseException { + NOT_YOUR_CHAT_ROOM( + HttpStatus.BAD_REQUEST, + "해당 채팅방에 대한 권한이 없습니다."), + NOT_FOUND_CHAT_ROOM( HttpStatus.BAD_REQUEST, "요청된 채팅방이 없습니다."); From 373bea37cbf31a0549a1f193019182145b90a6c3 Mon Sep 17 00:00:00 2001 From: luke Date: Wed, 22 May 2024 16:58:08 +0900 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=EC=B1=84=EB=84=90=20=ED=86=A0?= =?UTF-8?q?=ED=94=BD=20=EB=A1=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- be/src/main/java/yeonba/be/chatting/service/ChatService.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/be/src/main/java/yeonba/be/chatting/service/ChatService.java b/be/src/main/java/yeonba/be/chatting/service/ChatService.java index 2993d931..514d928e 100644 --- a/be/src/main/java/yeonba/be/chatting/service/ChatService.java +++ b/be/src/main/java/yeonba/be/chatting/service/ChatService.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.Optional; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; @@ -32,6 +33,7 @@ import yeonba.be.user.repository.block.BlockQuery; import yeonba.be.user.repository.user.UserQuery; +@Slf4j @Service @RequiredArgsConstructor public class ChatService { @@ -164,6 +166,7 @@ public void acceptRequestedChat(long userId, long notificationId) { // 메시지 수신을 위한 Redis Pub/Sub 구독 container.addMessageListener(adapter, new ChannelTopic(String.valueOf(chatRoom.getId()))); + log.info("channel topic 생성 {}", chatRoom.getId()); NotificationSendEvent notificationSendEvent = new NotificationSendEvent( NotificationType.CHATTING_REQUEST_ACCEPTED, receiver, sender, From 7ee962f43aec9e4387bcd187e5cc758496613405 Mon Sep 17 00:00:00 2001 From: luke Date: Fri, 24 May 2024 17:20:14 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix:=20=EC=98=A4=ED=83=80=20=EB=B0=8F=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95(#87)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../be/chatting/dto/response/ChatMessageResponse.java | 10 ++-------- .../java/yeonba/be/chatting/service/ChatService.java | 7 ++++--- be/src/main/java/yeonba/be/config/RedisConfig.java | 2 +- be/src/main/java/yeonba/be/config/WebSocketConfig.java | 2 -- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java b/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java index 4ba865af..10a7b0d1 100644 --- a/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java +++ b/be/src/main/java/yeonba/be/chatting/dto/response/ChatMessageResponse.java @@ -1,21 +1,15 @@ package yeonba.be.chatting.dto.response; import java.time.LocalDateTime; +import lombok.AllArgsConstructor; import lombok.Getter; @Getter +@AllArgsConstructor public class ChatMessageResponse { private long userId; private String userName; private String content; private LocalDateTime sentAt; - - public ChatMessageResponse(long userId, String userName, String content, LocalDateTime sentAt) { - - this.userId = userId; - this.userName = userName; - this.content = content; - this.sentAt = sentAt; - } } diff --git a/be/src/main/java/yeonba/be/chatting/service/ChatService.java b/be/src/main/java/yeonba/be/chatting/service/ChatService.java index 514d928e..f56ad3f9 100644 --- a/be/src/main/java/yeonba/be/chatting/service/ChatService.java +++ b/be/src/main/java/yeonba/be/chatting/service/ChatService.java @@ -44,13 +44,12 @@ public class ChatService { private final ChatMessageQuery chatMessageQuery; private final UserQuery userQuery; private final BlockQuery blockQuery; - private final NotificationQuery notificationQuey; + private final NotificationQuery notificationQuery; private final ApplicationEventPublisher eventPublisher; private final RedisChattingPublisher redisChattingPublisher; private final RedisChattingSubscriber adapter; private final RedisMessageListenerContainer container; - private final ChatRoomRepository chatRoomRepository; @Transactional public void publish(ChatPublishRequest request) { @@ -67,6 +66,7 @@ public void publish(ChatPublishRequest request) { new ChatMessage(chatRoom, sender, receiver, request.getContent(), request.getSentAt())); } + @Transactional(readOnly = true) public List getChatMessages(long userId, long roomId) { User user = userQuery.findById(userId); @@ -135,9 +135,10 @@ public void requestChat(long senderId, long receiverId) { eventPublisher.publishEvent(notificationSendEvent); } + @Transactional public void acceptRequestedChat(long userId, long notificationId) { - Notification notification = notificationQuey.findById(notificationId); + Notification notification = notificationQuery.findById(notificationId); // 채팅 요청 알림인지 검증 if (!notification.getType().isChattingRequest()) { diff --git a/be/src/main/java/yeonba/be/config/RedisConfig.java b/be/src/main/java/yeonba/be/config/RedisConfig.java index 0d1d250c..e71f7708 100644 --- a/be/src/main/java/yeonba/be/config/RedisConfig.java +++ b/be/src/main/java/yeonba/be/config/RedisConfig.java @@ -20,7 +20,7 @@ public class RedisConfig { private final ObjectMapper objectMapper; /** - * redis pub/sub 메시지 처리 listender 설정 + * redis pub/sub 메시지 처리 listener 설정 */ @Bean public RedisMessageListenerContainer redisMessageListenerContainer( diff --git a/be/src/main/java/yeonba/be/config/WebSocketConfig.java b/be/src/main/java/yeonba/be/config/WebSocketConfig.java index 3c078245..334d91bc 100644 --- a/be/src/main/java/yeonba/be/config/WebSocketConfig.java +++ b/be/src/main/java/yeonba/be/config/WebSocketConfig.java @@ -1,6 +1,5 @@ package yeonba.be.config; -import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.EnableWebSocket; @@ -10,7 +9,6 @@ @Configuration @EnableWebSocket -@RequiredArgsConstructor @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {