
HTTP의 한계
Ajax 등장
HTML5은 순수 웹 환경에서 실시간 양방향 통신이 가능해지게 만들었고, 이 명칭이 웹 소켓(Web Socket)입니다.
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version> <!-- 또는 최신 안정 버전 -->
        </dependency>
Gson
json 구조를 띄는 직렬화된 Data를 Java의 객체로 역직렬화, 직렬화 해주는 자바 라이브러리 입니다.
즉, JsonObject → JavaObject로 역직렬화
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){
        registry.addHandler(signalingSocketHandler(), "/ws/chat")
                .setAllowedOrigins("*");
    }
    @Bean
    public WebSocketHandler signalingSocketHandler() {
        return new SignalWebSocketHandler();
    }
}
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessage {
    private String type;
    private String sender;
    private String receiver;
    private Object data;
    public void setSender(String sender) {
        this.sender = sender;
    }
    public void newConnect(){
        this.type = "new-connect";
    }
    public void closeConnect(){
        this.type = "close-connect";
    }
    @Override
    public String toString() {
        return "Message{"+
                "type='" + type +'\'' +
                ", sender='" + sender +'\'' +
                ", receiver='" + receiver +'\''+
                ", data='" + data +'}';
    }
}
@Slf4j
@Component
public class SignalWebSocketHandler extends TextWebSocketHandler {
    private final Map<String, WebSocketSession> sessionList = new ConcurrentHashMap<>();
    // 웹 소켓 연결
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("[WebSocket session established]" + session.getId());
        String userId = session.getId();
        sessionList.put(userId, session);
        ChatMessage chatMessage = ChatMessage.builder()
                .sender(userId)
                .receiver("all")
                .build();
        chatMessage.newConnect();
        sessionList.values().forEach(s -> {
            try{
                if(s.getId().equals(userId)){
                    s.sendMessage(new TextMessage(chatMessage.toString()));
                }
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        });
    }
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        ChatMessage chatMessage = getObject(message.getPayload());
        chatMessage.setSender(session.getId());
        WebSocketSession receiver = sessionList.get(chatMessage.getReceiver());
        if(receiver != null && receiver.isOpen()){
            receiver.sendMessage(new TextMessage(chatMessage.toString()));
            log.info("[WebSocket received]" + session.getId());
        }
    }
    private ChatMessage getObject(String textMessage){
        Gson gson = new Gson();
        ChatMessage message = gson.fromJson(textMessage, ChatMessage.class);
        return message;
    }
    // 소켓 연결 종료
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String userId = session.getId();
        sessionList.remove(userId);
        final ChatMessage chatMessage = new ChatMessage();
        chatMessage.closeConnect();
        chatMessage.setSender(userId);
        sessionList.values().forEach(s -> {
            try {
                s.sendMessage(new TextMessage(chatMessage.toString()));
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        });
    }
    // 소켓 통신 에러
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
    }
}
postman 창 두개 띄워서 ws://localhost:8080/ws/chat 입력 후 Connect버튼을 눌러 두 사용자를 만들어 줍니다.
하나의 사용자에서 Message를 다른 사용자에 게 보냅니다.


4.그럼 Response에 반가워 라는 메세지가 도착했습니다.

간단하게 웹 소켓으로 채팅을 구현해보았습니다. 다음에는 채팅방을 추가하여 채팅의 고도화를 진행해보겠습니다.