네트워크에 공부한 뒤 공부한 내용을 복습할겸 겸사겸사 스프링 공부도 해보고 싶어서 Spring boot로 채팅 프로그램을 만들어 보려고 합니다. 일반적인 http통신을 하는 서버들과 달리 채팅 서버는 socket통신을 하는 서버가 필요합니다.
http통신
- client의 요청이 있을 때만 서버가 응답하고 연결을 종료하는 단방햔 통신 이다.
- 따라서 client가 server에 접속해 콘텐츠를 요청하고 결과를 받아 소비하는 구조의 서비스에서 많이 사용된다.
socket통신
- server와 client가 특정 port를 통해 지속적으로 연결유지 하여 실시간으로 양방향 통신을 하는 방식
- 주로 채팅 같은 실시간성을 요구하는 서비스에서 많이 사용된다.
Websocket
- Websocket은 기존의 단방향 HTTP프로토콜과 호환되어 양방향 통신을 제공하기 위해 개발된 프로토콜
- 일반 Socket통신과 달리 HTTP 80 port를 이용하므로 방화벽에 제약이 없다
- 접속까지는 HTTP 프로토콜을 이용하고 그 이후의 통신은 자체적인 Websocket 프로토콜로 통신하게 된다.
프로젝트 생성
- 프로젝트 생성은 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 |
---|