Yebali

WebSocket 구현하기 feat.Spring 본문

Spring

WebSocket 구현하기 feat.Spring

예발이 2023. 2. 10. 00:58

Spring+Kolin을 사용하여 웹 소켓을 구현하는 방법을 알아보자.

 

의존성 설정

build.gradle.kts에 아래처럼 의존성을 추가한다.

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-websocket")
}

WebSocket handler 설정하기

WebSocketHandler는 WebSocket을 통해 메시지를 전달받았을 때, 또는 누군가 WebSocket 연결하거나 종료했을 때의 동작을 담당하는 구현체이다. 

WebSocket이 전송할 수 있는 데이터의 형태는 Text와 Binary이기 때문에

WebSocketHandler도 TextWebSocketHandlerBinaryWebSocketHandler가 있다.

예시에서는 TextWebSocketHandler를 사용했다.

 

또한 Handler의 메서드는 오버라이드하여 그 동작을 재 정의 할 수 있다. 가장 흔하게 오버라이드 하는 함수는 아래 세 가지이다.

  • handleTextMessage() : WebSocket으로 메시지가 서버로 전송되었을 때 호출되는 메서드
    예시에서는 클라이언트가 메시지를 보내면 모든 클라이언트에게 동일한 메시지를 보낸다.
  • afterConnectionEstablished() : WebSocket에 클라이언트가 연결되었을 때 호출되는 메서드
  • afterConnectionCloesd() : 클라이언트가 연결을 종료했을 때 호출되는 메서드
@Component
class ChatHandler : TextWebSocketHandler() {
    val sessions = mutableSetOf<WebSocketSession>()

    // webSocket을 통해 메세지를 받았을 때 호출되는 메서드
    override fun handleTextMessage(session: WebSocketSession, message: TextMessage) {
        println("${session.id} send ${message.payload}")

        sessions.forEach {
            it.sendMessage(message)
        }
    }

    // webSocket 연결 후 호출되는 메서드
    override fun afterConnectionEstablished(session: WebSocketSession) {
        sessions.add(session)

        println("${session.id} is connected")
    }

    // webSocket 연결 해제 후 호출되는 메서드
    override fun afterConnectionClosed(session: WebSocketSession, status: CloseStatus) {
        sessions.remove(session)

        println("${session.id} is disconnected")
    }
}

 

WebSocketConfig 설정하기

앞서 설정한 WebSocketHandler를 Spring이 사용할 수 있도록 설정하는 과정이다.

@EnableWebSocket 애너테이션을 사용해 웹소켓 사용을 활성화하고,  registerWebSocketHandlers() 메서드를 오버라이드하여 구현한 WebSocketHandler를 추가한다.

registry.addHandler() 메서드에서 두 번째 파라미터로 들어가는 문자열은 추후 클라이언트가 WebSocket에 연결하기 위한 주소가 된다.

예를 들어 "/chat"을 넣었다면 해당 서버의 WebSocket에 접속하기 위한 주소는 "ws://<SERVER:IP_ADDR>:8080/chat"가 된다.

@Configuration
@EnableWebSocket
class WebSocketConfig(
    private val chatHandler: ChatHandler,
) : WebSocketConfigurer {
    override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
        // "ws://localhost:8080/chat"을 통해 web socket에 연결 가능하도록 설정
        registry.addHandler(chatHandler, "/chat")
            .setAllowedOrigins("*")
    }
}

WebSocket 사용 예시

WebSocket의 가장 흔한 사용 예시는 역시 채팅이다.

Flutter App

Flutter를 사용해 간단히 앱을 구현했으며 위 예시에서 설정된 것처럼 "ws://192.168.100.105:8080/chat"를 통해 사용해 서버의 WebSocket에 연결한다.

WebSocket이 연결되면 서로 다른 시뮬레이터에서 각자가 입력한 데이터가 다른 기기에 전송되어 간단한 채팅을 할 수 있다.

 

서버 로그에서도 클라이언트가 연결되고 서로 데이터를 주고 받는 것을 볼 수 있다.

 

WebSocket 예시 Github