네트워크에 공부한 뒤 공부한 내용을 복습할겸 겸사겸사 스프링 공부도 해보고 싶어서 Spring boot로 채팅 프로그램을 만들어 보려고 합니다. 일반적인 http통신을 하는 서버들과 달리 채팅 서버는 socket통신을 하는 서버가 필요합니다.

 

http통신

  • client의 요청이 있을 때만 서버가 응답하고 연결을 종료하는 단방햔 통신 이다.
  • 따라서 client가 server에 접속해 콘텐츠를 요청하고 결과를 받아 소비하는 구조의 서비스에서 많이 사용된다.

socket통신

  • server와 client가 특정 port를 통해 지속적으로 연결유지 하여 실시간으로 양방향 통신을 하는 방식
  • 주로 채팅 같은 실시간성을 요구하는 서비스에서 많이 사용된다.

Websocket

  • Websocket은 기존의 단방향 HTTP프로토콜과 호환되어 양방향 통신을 제공하기 위해 개발된 프로토콜
  • 일반 Socket통신과 달리 HTTP 80 port를 이용하므로 방화벽에 제약이 없다
  • 접속까지는 HTTP 프로토콜을 이용하고 그 이후의 통신은 자체적인 Websocket 프로토콜로 통신하게 된다.

프로젝트 생성

start.spring.io에서 선택한 버전과 dependencies 정보

  • 프로젝트 생성은 start.spring.io에서 만들었습니다.

 

 

기본 메인 메소드

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TestApplication {

	public static void main(String[] args) {
		SpringApplication.run(TestApplication.class, args);
	}

}

프로젝트를 생성할 때 기본 메소드 그대로 사용하면 됩니다.

 

 

 

Websocket Handler 작성

import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.logging.Logger;

@Component
public class WebSocketChatHandler extends TextWebSocketHandler {

    private final static Logger LOG = Logger.getGlobal();

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String input = message.getPayload();
        LOG.info(input); // 채팅 log
        TextMessage textMessage = new TextMessage("Hello, 영진일지입니다. \n 웹소켓 테스트입니다.");
        session.sendMessage(textMessage);
    }
}

websocket 통신은 서버와 클라이언트가 1:N 으로 관계를 맺습니다. 따라서 한 서버에 여러 클라이언트가 접속 할 수 있으며, 서버에는 여러 클라이언트가 발송한 메시지를 받아 처리해줄 Handler의 작성이 필요합니다. 다음과 같이 TextWebSocketHandler 를 상속받아 Handler를 작성했습니다. Client로부터 받은 메시지를 콘솔에 출력하고 Client로 환영 메시지를 보내는 역할을 합니다.

 

 

 

Websocket Config 작성

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    private final WebSocketHandler webSocketHandler;

    public WebSocketConfig(WebSocketHandler webSocketHandler) {
        this.webSocketHandler = webSocketHandler;
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(webSocketHandler, "/ws/chat").setAllowedOrigins("*");
    }
}

방금전 만든 handler 를 이용하여 Websocket을 활성화 하기 위한 Config 파일을 작성했습니다.

@EnableWebSocket을 선언하여 Websocket을 활성화합니다.

Websocket에 접속하기 위한 endpoint는 /ws/chat으로 설정하고 도메인이 다른 서버에서도 접속 가능하도록 CORS 설정을 추가해줍니다. (여기서 endpoint 접근 url입니다. url:port번호 후 뒤에 붙는 문자열을 의미합니다.)

 

 

Websocket 테스트

 

테스트를 위한 클라이언트 대신 chrome 웹스토어에 있는 Simple Websocket Client를 설치하고 실행합니다.

Spring Boot 서버를 구동 후 설치한 확장프로그램 Simple WebSocket Client 를 실행하고 ws://localhost:8080/ws/chat 를 입력후 Open 을 누릅니다.

 

Websocket의 경우 별개의 프로토콜이므로 http 가 아닌 ws로 시작하는 주소체계를 갖습니다.

위는 Message Log창에 서버와 연결이 되어 서버로 부터 작성한 메세지가 오는 모습입니다.

 

또한 위의 사진은 스프링 서버에 전송온 Simple WebSocket Client에서 작성한 Request 메세지가 잘 전달된 모습입니다.

 

위와 같이 TCP/IP를 이용하여 클라이언트 대용인 Simple WebSocket Client와 서버인 Spring과의 3-way-handshake를 통한 연결 후 데이터를 전송하는 모습입니다.

'spring' 카테고리의 다른 글

[Spring] 빌드 툴(Ant, Maven, Gradle)  (0) 2021.10.28

+ Recent posts