의존성 추가하기
- build.gradle
dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:sockjs-client:1.5.1'
implementation 'org.webjars:stomp-websocket:2.3.4'
}
Config 파일 수정
@Configuration
@EnableWebSocketMessageBroker
public class StompWebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat")
.setAllowedOrigins("http://localhost:8080")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/pub");
registry.enableSimpleBroker("/sub");
}
}
WebSocketMessageBrokerConfigurer를 구현한다.
ChatRoom 구현
@Getter
@Builder
@Entity
public class ChatRoom {
@Id
private String id;
private String name;
public static ChatRoom create(String name) {
ChatRoom chatRoom = new ChatRoom();
chatRoom.id = UUID.randomUUID().toString();
chatRoom.name = name;
return chatRoom;
}
}
ChatMessage 구현
@Getter
@Builder
@Entity
public class ChatMessage {
@Id @GeneratedValue(strategy = IDENTITY)
private Long id;
private String roomId;
private String sender;
private String message;
}
Repository
public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
}
public interface ChatMessageRepository extends JpaRepository<ChatMessage, Long> {
}
ChatRoomService
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ChatRoomService {
private final ChatRoomRepository chatRoomRepository;
@Transactional
public ChatRoom create(String name) {
ChatRoom chatRoom = ChatRoom.builder().name(name).build();
chatRoomRepository.save(chatRoom);
return chatRoom;
}
public ChatRoom findById(Long id) {
Optional<ChatRoom> chatRoom = chatRoomRepository.findById(id);
if (chatRoom.isEmpty()) {
// [ErrorCode] 존재하지 않는 채팅방입니다.
}
return chatRoom.get();
}
public List<ChatRoom> findAll() {
return chatRoomRepository.findAll();
}
}
ChatController
@Controller
@RequiredArgsConstructor
public class ChatMessageController {
private final ChatMessageService chatMessageService;
private final SimpMessageSendingOperations messagingTemplate;
@MessageMapping("/chat/message")
public void message(ChatMessage message) {
messagingTemplate.convertAndSend("/sub/chat/room/%d".formatted(message.getRoomId()));
}
}
ChatRoomController
@RequiredArgsConstructor
@Controller
@RequestMapping("/chat")
public class ChatRoomController {
private final ChatRoomService chatRoomService;
@GetMapping("/room/{id}")
public String showRoom(@PathVariable Long id, Model model) {
ChatRoom room = chatRoomService.findById(id);
model.addAttribute("room", room);
return "chat/room";
}
@GetMapping("/rooms")
public String findAll(Model model) {
List<ChatRoom> chatRooms = chatRoomService.findAll();
model.addAttribute("chatRooms", chatRooms);
return "chat/rooms";
}
@PostMapping("/create")
public String create(@RequestParam String name) {
ChatRoom chatRoom = chatRoomService.create(name);
return "redirect:/room/%d".formatted(chatRoom.getId());
}
}
뷰 단 생성과 테스트는 아직이다...
글을 작성하면서 블로그를 참고한 내용과 직접 작성한 내용을 섞어놔서 말이 안 되는(?) 부분이 있을 수도 있다.
내 경우에는 RDB를 사용하는 것을 가정하고 구현했고, 여러 블로그들의 포스트 내용은 Map<String, ChatRoom>을 생성해서 DB 대신 사용하는 내용이기 때문이다. ChatMessage와 ChatRoom의 내용도 다르지만 이 부분은 내 코드와 똑같이 구현하려면 다른 엔티티도 만들어야 하는 등의 문제가 있어 다른 블로그들의 내용과 좀더 비슷하게 작성했다.
'프로젝트 & TIL > 일별 공부 기록 (백엔드 스쿨)' 카테고리의 다른 글
85일차 - MongoDB Replica Set vs Sharded Cluster, Strorage Engine (0) | 2023.06.23 |
---|---|
84일차 - MongoDB Sharded Cluster (0) | 2023.06.22 |
82일차 - 웹소켓을 이용한 기본적인 채팅 기능 구현하기 (0) | 2023.06.21 |
81일차 - 프로젝트 진행 시 참고사항 (0) | 2023.06.19 |
80일차 - MongoDB Replica Set (0) | 2023.06.16 |