본문 바로가기

Web

Java WebSocket ping handler 는 어디에 구현되어 있을까?

Spring의 AbstractWebSocketHandler 를 확인해보면, textMessage, BinaryMessage, PongMessage의 handler는 구현할 수 있게 되어있으나, pingMessag의 handler는 구현할 수 없게 되어있다. 그렇다면, PingMessage 누가 handle 하고 있는것일까?
( AbstractWebSocketHandler document : https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/socket/handler/AbstractWebSocketHandler.html )

정답은 tomcat에서 해준다.
톰켓 홈페이지를 가서 Websocket의 설명을 읽어보면, JSR-356에 정의된 Java WebSocket 1.1 API 를 구현한다라고 설명이 되었다.

Tomcat implements the Java WebSocket 1.1 API defined by JSR-356.
출처 : https://tomcat.apache.org/tomcat-8.5-doc/web-socket-howto.html
 

Apache Tomcat 8 (8.5.91) - WebSocket How-To

Tomcat provides support for WebSocket as defined by RFC 6455. Tomcat implements the Java WebSocket 1.1 API defined by JSR-356. There are several example applications that demonstrate how the WebSocket API can be used. You will need to look at both the clie

tomcat.apache.org

저 JSR-356 스펙을 확인해보면, WebSocket 구현체는 ping message를 peer로부터 수신하게 되면, 동일한 어플리케이션 데이터를 가진 pong message를 가능한 빨리 peer에게 응답해야한다고 적혀있다.

The ping/pong mechanism in the WebSocket protocol serves as a check that the connection is still active. Following the requirements of the protocol, if a WebSocket implementation receives a ping message from a peer, it must respond as soon as possible to that peer with a pong message containing the same application data [WSC 2.2.5-1].
출처 : https://jakarta.ee/specifications/websocket/2.1/jakarta-websocket-spec-2.1.html#pings-and-pongs
 

Jakarta WebSocket Specification

WebSocket applications are configured with a number of key parameters: the path mapping that identifies a WebSocket endpoint in the URI-space of the container, the subprotocols that the endpoint supports, and the extensions that the application requires. A

jakarta.ee

톰캣이 WebSocket API를 구현하고 있기 때문에, Ping Message를 수신 받으면 톰캣에서 Pong message를 반환하고 있다.
실제로 tomcat의 코드를 찾아보면, 아래와 같은 코드가 구현되어있는 것을 확인할 수 있다.

        } else if (opCode == Constants.OPCODE_PING) {
            if (wsSession.isOpen()) {
                wsSession.getBasicRemote().sendPong(controlBufferBinary);
            }

출처 : https://github.com/apache/tomcat/blob/a903a28dd14055b6537a33904baef875b68678d8/java/org/apache/tomcat/websocket/WsFrameBase.java#L348-L351

반응형

'Web' 카테고리의 다른 글

Mixed Content 해결 방법  (0) 2021.09.05