티스토리 뷰

1. 클라이언트와는 SockJS로 연결해서 통신한다.

2. WebSocket + STOMP 를 사용한다

 

[목적]

클라이언트가 보내주는 이벤트를 같은 방을 구독하고 있는 팀원들에게 뿌려준다.

 

WebSocketConfig

@Slf4j
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        /*
         Subscribe
         [/sub/comm/room/ + {roomId}]
         */
        registry.enableSimpleBroker("/sub");

        /*
         Message Publish
         1. [/pub/comm/message/]
         2. [/pub/comm/item/]
         */
        registry.setApplicationDestinationPrefixes("/pub");
    }
}

 

먼저 소켓을 /ws-swoomi를 엔드포인트로 핸드쉐이크를 통해 커넥션을 갖게한다.

 

MsgController

    /***
     * publish [pub/comm/message/{teamId}]
     */
    @MessageMapping("/comm/message/{teamId}")
    @SendTo("/sub/comm/room/{teamId}")
    public Message message(@DestinationVariable String teamId,
                           Message message) {
        return message;
    }

    /*
    publish [pub/comm/item/{teamId}]
     */
    @MessageMapping("/comm/item/{teamId}")
    @SendTo("/sub/comm/item/{teamId}")
    public ItemMessage message(@DestinationVariable String teamId,
                               ItemMessage itemMessage) {

        log.info("Item Message : " + itemMessage.toString());

        if (championInfoRepo.findBySummonerName(itemMessage.getSummonerName()).isEmpty()) {
            championInfoService.calculateAndSaveChampionInfo(itemMessage.getSummonerName(), 1);
        }

        for (String itemName : itemMessage.getItemNames()) {
            ItemPurchaseOneDto itemDto = ItemPurchaseOneDto.builder()
                    .matchTeamCode(teamId)
                    .itemName(itemName)
                    .summonerName(itemMessage.getSummonerName())
                    .championName(itemMessage.getChampionName())
                    .build();

            if (itemMessage.getMethod().equals("DELETE") && itemMessage.getType().equals("ITEM")) {
                itemPurchaseService.deletePurchaseItem(itemDto);
            } else {
                itemPurchaseService.setPurchaseItem(itemDto);
            }
        }

        return itemMessage;
    }

방 동기화를 위해 필요한 정보별로 소켓 통신을 하게된다.

 

@MessageMapping으로 요청이 들어오면 @SendTo로 들어온 요청(메세지)를 전부 브로드캐스팅 하게된다. 이때 프론트에서 동일 방 인원들에 대해 Subscribe를 걸어놓는다.

 

백엔드에서는 브로드캐스팅 하기전에 필요한 로직을 중간에 수행하면 된다.

반응형
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday