[TIL] 항해99 Day 57

woonie·2022년 3월 8일
0

TIL

목록 보기
46/64
post-custom-banner

항해 57일차 2022.03.07

websocket을 이용해서 서버/클라이언트 통신을 구현해봤다.
메시징 전송을 조금 더 효율적으로 하기 위해 Stomp 프로토콜을 사용해봤다.
pub/sub 구조로 되어 있고 메시지를 발송 / 처리하는 부분이 확실히 정해져 있다.

  • pub/sub란?
    메시지를 공급하는 주체와 소비하는 주체를 분리하여 제공하는 메시지 방법이다.
    • 채팅방 생성 - pub/sub 구현을 위한 Topic 생성
    • 채팅방 입장 - Topic을 구독
    • 채팅방에서 메시지를 보내고 받는다 - 해당 Topic으로 메시지를 발송(pub) 또는 메시지를 받는다(sub)

build.gradle

 implementation 'org.webjars:sockjs-client:1.0.2'
 implementation 'org.webjars:stomp-websocket:2.3.3'

sockjs는 websocket을 지원하지 않는 낮은 버전의 브라우저에서도 websocket을 사용할 수 있도록 해주는 라이브러리다.

WebSockConfig

  • Stomp를 사용하기 위해 @EnableWebSocketMessageBroker을 선언
  • pub/sub 메시징 구현을 위해 각 prefix는 /pub , /sub으로 시작하도록 설정
  • Stomp websocket의 연결 endpoint는 /ws-stomp로 설정
@Configuration
@EnableWebSocketMessageBroker
public class WebSockConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/sub");
        config.setApplicationDestinationPrefixes("/pub");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws-stomp").setAllowedOrigins("*")
                .withSockJS();
    }
}

Repository

  • 채팅방을 생성하고 조회하는 Repository생성

@Repository
public class ChatRoomRepository {

    private Map<String, ChatRoom> chatRoomMap;

    @PostConstruct
    private void init() {
        chatRoomMap = new LinkedHashMap<>();
    }

    public List<ChatRoom> findAllRoom() {
        // 채팅방 생성순서 최근 순으로 반환
        List chatRooms = new ArrayList<>(chatRoomMap.values());
        Collections.reverse(chatRooms);
        return chatRooms;
    }

    public ChatRoom findRoomById(String id) {
        return chatRoomMap.get(id);
    }

    public ChatRoom createChatRoom(String name) {
        ChatRoom chatRoom = ChatRoom.create(name);
        chatRoomMap.put(chatRoom.getRoomId(), chatRoom);
        return chatRoom;
    }
}

ChatRoomController



@RequiredArgsConstructor
@Controller
@RequestMapping("/chat")
public class ChatRoomController {

    private final com.spring.wschat.repo.ChatRoomRepository chatRoomRepository;

    // 채팅 리스트 화면
    @GetMapping("/room")
    public String rooms(Model model) {
        return "/chat/room";
    }
    // 모든 채팅방 목록 반환
    @GetMapping("/rooms")
    @ResponseBody
    public List<ChatRoom> room() {
        return chatRoomRepository.findAllRoom();
    }
    // 채팅방 생성
    @PostMapping("/room")
    @ResponseBody
    public ChatRoom createRoom(@RequestParam String name) {
        return chatRoomRepository.createChatRoom(name);
    }
    // 채팅방 입장 화면
    @GetMapping("/room/enter/{roomId}")
    public String roomDetail(Model model, @PathVariable String roomId) {
        model.addAttribute("roomId", roomId);
        return "/chat/roomdetail";
    }
    // 특정 채팅방 조회
    @GetMapping("/room/{roomId}")
    @ResponseBody
    public ChatRoom roomInfo(@PathVariable String roomId) {
        return chatRoomRepository.findRoomById(roomId);
    }
}
profile
동료들과 함께하는 개발의 중요성에 관심이 많습니다. 언제나 호기심을 갖고 꾸준히 노력하는 개발자로서 성장하고 있습니다.
post-custom-banner

0개의 댓글