From 0020eea0872f9ff5d639c62ef4ae35b8eb9d40eb Mon Sep 17 00:00:00 2001 From: su080915 Date: Mon, 26 Aug 2024 22:51:55 +0900 Subject: [PATCH] feat :: chat --- crescendo-server/build.gradle | 2 +- .../domain/chat/config/WebSockConfig.java | 20 +++++++ .../chat/controller/ChatController.java | 29 ++++++++++ .../chat/hadler/WebSockChatHandler.java | 29 ++++++++++ .../domain/chat/message/ChatMessage.java | 23 ++++++++ .../domain/chat/room/ChatRoom.java | 35 ++++++++++++ .../domain/chat/service/ChatService.java | 57 +++++++++++++++++++ 7 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/config/WebSockConfig.java create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/controller/ChatController.java create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/hadler/WebSockChatHandler.java create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/message/ChatMessage.java create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/room/ChatRoom.java create mode 100644 crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/service/ChatService.java diff --git a/crescendo-server/build.gradle b/crescendo-server/build.gradle index 8133571..32c47a4 100644 --- a/crescendo-server/build.gradle +++ b/crescendo-server/build.gradle @@ -61,7 +61,7 @@ dependencies { implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter:1.0.0-SNAPSHOT' // 소켓 통신 -// implementation 'org.springframework.boot:spring-boot-starter-websocket' + implementation 'org.springframework.boot:spring-boot-starter-websocket' } diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/config/WebSockConfig.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/config/WebSockConfig.java new file mode 100644 index 0000000..f0952de --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/config/WebSockConfig.java @@ -0,0 +1,20 @@ +package com.example.crescendoserver.domain.chat.config; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@RequiredArgsConstructor +@Configuration +@EnableWebSocket +public class WebSockConfig implements WebSocketConfigurer { + private final WebSocketHandler webSocketHandler; + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler, "/ws/chat").setAllowedOrigins("*"); + } +} \ No newline at end of file diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/controller/ChatController.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/controller/ChatController.java new file mode 100644 index 0000000..925072a --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/controller/ChatController.java @@ -0,0 +1,29 @@ +package com.example.crescendoserver.domain.chat.controller; + +import com.example.crescendoserver.domain.chat.room.ChatRoom; +import com.example.crescendoserver.domain.chat.service.ChatService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/chat") +public class ChatController { + private final ChatService chatService; + + @PostMapping + public ChatRoom createRoom(@RequestParam String name) { + return chatService.createRoom(name); + } + + @GetMapping + public List findAllRoom() { + return chatService.findAllRoom(); + } +} diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/hadler/WebSockChatHandler.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/hadler/WebSockChatHandler.java new file mode 100644 index 0000000..4072f67 --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/hadler/WebSockChatHandler.java @@ -0,0 +1,29 @@ +package com.example.crescendoserver.domain.chat.hadler; + +import com.example.crescendoserver.domain.chat.message.ChatMessage; +import com.example.crescendoserver.domain.chat.room.ChatRoom; +import com.example.crescendoserver.domain.chat.service.ChatService; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +@Slf4j +@RequiredArgsConstructor +@Component +public class WebSockChatHandler extends TextWebSocketHandler { + private final ObjectMapper objectMapper; + private final ChatService chatService; + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + String payload = message.getPayload(); + log.info("payload {}", payload); + ChatMessage chatMessage = objectMapper.readValue(payload, ChatMessage.class); + ChatRoom room = chatService.findRoomById(chatMessage.getRoomId()); + room.handleActions(session, chatMessage, chatService); + } +} \ No newline at end of file diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/message/ChatMessage.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/message/ChatMessage.java new file mode 100644 index 0000000..456be3b --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/message/ChatMessage.java @@ -0,0 +1,23 @@ +package com.example.crescendoserver.domain.chat.message; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@Builder +@Getter +@Setter +@RequiredArgsConstructor +@AllArgsConstructor +public class ChatMessage { + // 메시지 타입 : 입장, 채팅 + public enum MessageType { + ENTER, TALK + } + private MessageType type; // 메시지 타입 + private String roomId; // 방번호 + private String sender; // 메시지 보낸사람 + private String message; // 메시지 +} \ No newline at end of file diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/room/ChatRoom.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/room/ChatRoom.java new file mode 100644 index 0000000..1dea14d --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/room/ChatRoom.java @@ -0,0 +1,35 @@ +package com.example.crescendoserver.domain.chat.room; + +import com.example.crescendoserver.domain.chat.message.ChatMessage; +import com.example.crescendoserver.domain.chat.service.ChatService; +import lombok.Builder; +import lombok.Getter; +import org.springframework.web.socket.WebSocketSession; + +import java.util.HashSet; +import java.util.Set; + +@Getter +public class ChatRoom { + private String roomId; + private String name; + private Set sessions = new HashSet<>(); + + @Builder + public ChatRoom(String roomId, String name) { + this.roomId = roomId; + this.name = name; + } + + public void handleActions(WebSocketSession session, ChatMessage chatMessage, ChatService chatService) { + if (chatMessage.getType().equals(ChatMessage.MessageType.ENTER)) { + sessions.add(session); + chatMessage.setMessage(chatMessage.getSender() + "님이 입장했습니다."); + } + sendMessage(chatMessage, chatService); + } + + public void sendMessage(T message, ChatService chatService) { + sessions.parallelStream().forEach(session -> chatService.sendMessage(session, message)); + } +} diff --git a/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/service/ChatService.java b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/service/ChatService.java new file mode 100644 index 0000000..d290b3d --- /dev/null +++ b/crescendo-server/src/main/java/com/example/crescendoserver/domain/chat/service/ChatService.java @@ -0,0 +1,57 @@ +package com.example.crescendoserver.domain.chat.service; + +import com.example.crescendoserver.domain.chat.room.ChatRoom; +import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.PostConstruct; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Slf4j +@RequiredArgsConstructor +@Service +public class ChatService { + + private final ObjectMapper objectMapper; + private Map chatRooms; + + @PostConstruct + private void init() { + chatRooms = new LinkedHashMap<>(); + } + + public List findAllRoom() { + return new ArrayList<>(chatRooms.values()); + } + + public ChatRoom findRoomById(String roomId) { + return chatRooms.get(roomId); + } + + public ChatRoom createRoom(String name) { + String randomId = UUID.randomUUID().toString(); + ChatRoom chatRoom = ChatRoom.builder() + .roomId(randomId) + .name(name) + .build(); + chatRooms.put(randomId, chatRoom); + return chatRoom; + } + + public void sendMessage(WebSocketSession session, T message) { + try { + session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message))); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } +}