728x90
채팅 고도화
ChatMessage
- 채팅 메시지를 주고받기 위한 DTO
@Getter
@Setter
public class ChatMessage {
// 메시지 타입 : 입장, 채팅
public enum MessageType {
ENTER, TALK
}
private MessageType type; // 메시지 타입
private String roomId; // 방번호
private String sender; // 메시지 보낸사람
private String message; // 메시지
}
ChatRoom
- 채팅방을 구현하기 위한 DTO
- 채팅방은 입장한 클라이언트들의 정보를 가지고 있어야 하므로 WebsocketSession 정보 리스트를 멤버 필드로 갖는다.
- 채팅방은 입장,대화하기의 기능이 있으므로 handleAction을 통해 처리
- 입장 시 채팅방의 session정보에 클라이언트의 session리스트에 추가 후 채팅방 메세지가 도착할 경우 채팅방의 모든 session에 메시지를 발송하면 된다.
@Getter
public class ChatRoom {
private String roomId;
private String name;
private Set<WebSocketSession> 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 <T> void sendMessage(T message, ChatService chatService) {
sessions.parallelStream().forEach(session -> chatService.sendMessage(session, message));
}
}
ChatService
- 채팅방을 생성, 조회, 하나의 session에 메시지 발송을 하는 서비스 구현
- 채팅방 Map은 서버에 생성된 모든 채팅방의 정보를 모아둔다.
- 채팅방 조회 = 채팅방 Map에 담긴 정보 조회
- 채팅방 생성 - Random UUID로 구별ID를 가진 채팅방 객체 생성하고 Map에 추가
- 메시지 발송 - 지정한 websocket session에 메시지 발송
@Slf4j
@RequiredArgsConstructor
@Service
public class ChatService {
private final ObjectMapper objectMapper;
private Map<String, ChatRoom> chatRooms;
@PostConstruct
private void init() {
chatRooms = new LinkedHashMap<>();
}
public List<ChatRoom> 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 <T> void sendMessage(WebSocketSession session, T message) {
try {
session.sendMessage(new TextMessage(objectMapper.writeValueAsString(message)));
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
Controller
@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<ChatRoom> findAllRoom() {
return chatService.findAllRoom();
}
}
'Spring' 카테고리의 다른 글
Travis CI 연동 (1) (0) | 2024.04.16 |
---|---|
CI/CD (1) | 2024.04.16 |
S3로 파일 업로드 (0) | 2024.04.15 |
트랜잭션의 ACID란? (0) | 2024.04.15 |
트랜잭션(Transaction) (0) | 2024.04.15 |