[SpringBoot/STOMP] 모바일 기기와 통신 시 Socket 정상 종료를 위한 heartbeat 적용하기

 

 

 

다 된 줄 알았는데 

😑(모바일):제가 STOMP Connect가 된 건지 안 된 건지 모르겠어요

🍊: 어, Swift 라이브러리 stompClientDidConnect 등의 메소드로 수신되지 않으시나요?

😑(모바일): 연결이 끊겨도 걔가 이미 연결되어있는 것처럼 응답이 와요.

🍊..... 😱: 헐

😑(모바일): 그래서 재연결할 타이밍을 못 잡아요

🍊: 잠시 기다려주세요, 방법 찾아볼게요.

 

 

왜 그랬을까?

 

WebSocket Server에서 Connection 'close' 이벤트를 받지 못할 때

(2020-08-17에 작성된 글입니다) WebSocket 서버를 운영하다보면 가끔 Client WebSocket Connection이 끊겨졌음에도 서버에서는 close이벤트를 수신하지 못할 때가 있다. 아마 WebSocket 서버에서 WebSocket Connection

devs0n.tistory.com

위의 글을 참고로 생각해보자.

요약하면 "클라이언트가 일방적으로 네트워크를 끊을 경우, 서버는 클라이언트의 종료 의사를 알지 못한다"

STOMP 모델도 WebSocket을 사용하여 동작하고 있고, 그 WebSocket은 TCP 기반 프로토콜이기 때문에 TCP 3-way handshake가 이루어진다. 이는 연결 종료 시점에도 handshake가 이루어는 게 정상인데, 그 과정이 제대로 이루어지질 않으니 서버는 이미 넌 나와 연결되어있지롱 하는 응답이 가는 거다.

 

 

해결방법: hearbeat 체크하기

    /***
     * @param registry 등록할 브로커 객체
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/{...}", "/{...}", "/{...}")
                .setHeartbeatValue(new long[]{0, 10000})  // 서버X, 클라이언트의 10초 주기 Ping 기대
                .setTaskScheduler(taskScheduler());
      ...
    }

 

STOMP는 자체적으로 heart-beating이라는 기능을 지원한다. STOMP 프로토콜의 명세에 따르면, 클라이언트와 서버는 서로 주기적으로 heart-beat 메시지를 교환할 수 있으며 이를 통해 연결이 정상적으로 유지되고 있는지 확인할 수 있다.

위의 설정에 따르면 클라이언트가 일정 시간동안 heart-beat 메시지를 보내지 않는다면 서버는 연결이 끊어진 것으로 판단하고 연결을 정상 종료한다. new long[] 배열의 첫 번째 원소는 0을 주었는데, 이는 서버에서 ping을 날리는 주기로서, 0으로 만들어 안 날리겠다는 의미를 내포한다. 다만 클라이언트는 10초 주기의 통신을 보내기를 기대하는 상황이다.

 

   func openConnection() {
        let url = NSURL(string: "ws://{url}/ws")
        socketClient = StompClientLib()
        let headers = ["heart-beat": "10000, 0"] // heartbeat 설정 (ms 단위)

        socketClient.openSocketWithURLRequest(request: NSURLRequest(url: url! as URL), delegate: self, connectionHeaders: headers)
    }

그렇다면 그 기대에 맞게 Client도 heartbeat를 일정 주기에 맞게 보내면된다.

만약 통신상태가 걱정된다면, 서버보다는 더 빠른 주기를 맞추어 충족시키는 방법이 있을 것이다.

 

 

 

 

 

WebSocket Server에서 Connection 'close' 이벤트를 받지 못할 때

(2020-08-17에 작성된 글입니다) WebSocket 서버를 운영하다보면 가끔 Client WebSocket Connection이 끊겨졌음에도 서버에서는 close이벤트를 수신하지 못할 때가 있다. 아마 WebSocket 서버에서 WebSocket Connection

devs0n.tistory.com

 

 

WebSocket 연결이 비정상적으로 끊어졌을 때 핸들링하기

만약 WebSocket이 원인 미상의 사고로 인해 연결이 끊어진다면?

velog.io