Loading...
Spring Framework Reference Documentation 7.0.2의 WebSocket API의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
See equivalent in the Reactive stack
Spring Framework는 WebSocket 메시지를 처리하는 client- 및 server-side 애플리케이션을 작성하는 데 사용할 수 있는 WebSocket API를 제공합니다.
WebSocketHandlerSee equivalent in the Reactive stack
WebSocket 서버를 생성하는 것은 WebSocketHandler를 구현하거나, 더 일반적으로는 TextWebSocketHandler 또는 BinaryWebSocketHandler를 확장하는 것만큼 간단합니다. 다음 예제는 TextWebSocketHandler를 사용합니다:
1public class MyHandler extends TextWebSocketHandler { 2 3 @Override 4 protected void handleTextMessage(WebSocketSession session, TextMessage message) { 5 // ... 6 } 7}
1class MyHandler : TextWebSocketHandler() { 2 3 override fun handleTextMessage(session: WebSocketSession, message: TextMessage) { 4 // ... 5 } 6}
앞의 WebSocket 핸들러를 특정 URL에 매핑하기 위한 전용 WebSocket 프로그래매틱 설정 및 XML 네임스페이스 지원가 있으며, 다음 예제와 같습니다:
1@Configuration 2@EnableWebSocket 3public class WebSocketConfiguration implements WebSocketConfigurer { 4 5 @Override 6 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 7 registry.addHandler(myHandler(), "/myHandler"); 8 } 9 10 @Bean 11 public WebSocketHandler myHandler() { 12 return new MyHandler(); 13 } 14}
1@Configuration 2@EnableWebSocket 3class WebSocketConfiguration : WebSocketConfigurer { 4 5 override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { 6 registry.addHandler(myHandler(), "/myHandler") 7 } 8 9 @Bean 10 fun myHandler(): WebSocketHandler { 11 return MyHandler() 12 } 13}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:websocket="http://www.springframework.org/schema/websocket" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 https://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/websocket 8 https://www.springframework.org/schema/websocket/spring-websocket.xsd"> 9 10 <websocket:handlers> 11 <websocket:mapping path="/myHandler" handler="myHandler"/> 12 </websocket:handlers> 13 14 <bean id="myHandler" class="org.springframework.docs.web.websocket.websocketserverhandler.MyHandler"/> 15 16</beans>
앞의 예제는 Spring MVC 애플리케이션에서 사용하기 위한 것이며 DispatcherServlet의 설정에 포함되어야 합니다. 그러나 Spring의 WebSocket 지원는 Spring MVC에 의존하지 않습니다. WebSocketHandler를 다른 HTTP-serving 환경에 통합하는 것은 WebSocketHttpRequestHandler의 도움으로 비교적 간단합니다.
WebSocketHandler API를 STOMP 메시징과 같이 간접적으로가 아니라 직접 사용할 때, 애플리케이션은 메시지 전송을 동기화해야 합니다. 이는 기본 standard WebSocket 세션(JSR-356)이 concurrent 전송을 허용하지 않기 때문입니다. 한 가지 옵션은 WebSocketSession을 ConcurrentWebSocketSessionDecorator로 감싸는 것입니다.
See equivalent in the Reactive stack
초기 HTTP WebSocket 핸드셰이크 요청를 커스터마이즈하는 가장 쉬운 방법은 “before” 및 “after” 핸드셰이크에 대한 메서드를 노출하는 HandshakeInterceptor를 사용하는 것입니다. 이러한 인터셉터를 사용하여 핸드셰이크를 차단하거나 어떤 attribute든 WebSocketSession에서 사용할 수 있도록 만들 수 있습니다. 다음 예제는 HTTP 세션 attribute를 WebSocket 세션으로 전달하기 위해 내장된 인터셉터를 사용합니다:
1@Configuration 2@EnableWebSocket 3public class WebSocketConfiguration implements WebSocketConfigurer { 4 5 @Override 6 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 7 registry.addHandler(new MyHandler(), "/myHandler") 8 .addInterceptors(new HttpSessionHandshakeInterceptor()); 9 } 10 11}
1@Configuration 2@EnableWebSocket 3class WebSocketConfiguration : WebSocketConfigurer { 4 5 override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { 6 registry.addHandler(MyHandler(), "/myHandler") 7 .addInterceptors(HttpSessionHandshakeInterceptor()) 8 } 9}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:websocket="http://www.springframework.org/schema/websocket" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 https://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/websocket 8 https://www.springframework.org/schema/websocket/spring-websocket.xsd"> 9 10 <websocket:handlers> 11 <websocket:mapping path="/myHandler" handler="myHandler"/> 12 <websocket:handshake-interceptors> 13 <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> 14 </websocket:handshake-interceptors> 15 </websocket:handlers> 16 17 <bean id="myHandler" class="org.springframework.docs.web.websocket.websocketserverhandler.MyHandler"/> 18 19</beans>
더 고급 옵션은 WebSocket 핸드셰이크의 단계를 수행하는 DefaultHandshakeHandler를 확장하는 것입니다. 여기에는 client origin을 검증하고, sub-protocol을 협상하는 것과 기타 세부 사항이 포함됩니다. 애플리케이션은 아직 지원되지 않는 WebSocket 서버 엔진 및 버전에 적응하기 위해 custom RequestUpgradeStrategy를 설정해야 하는 경우에도 이 옵션을 사용해야 할 수 있습니다(이 주제에 대한 자세한 내용은 Deployment를 참조하십시오). Java 설정과 XML 네임스페이스 모두 custom HandshakeHandler를 설정할 수 있게 해줍니다.
Spring은 추가 동작으로
WebSocketHandler를 데코레이트하는 데 사용할 수 있는WebSocketHandlerDecoratorbase class를 제공합니다.<br>로깅 및 예외 처리 구현이 제공되며 WebSocket Java 설정 또는 XML 네임스페이스를 사용할 때 기본적으로 추가됩니다.<br>ExceptionWebSocketHandlerDecorator는 어떤WebSocketHandler메서드에서 발생하는 모든 처리되지 않은 예외를 catch하고<br>서버 오류를 나타내는 status1011로 WebSocket 세션을 닫습니다.
Spring WebSocket API는 DispatcherServlet이 HTTP WebSocket 핸드셰이크와 다른 HTTP 요청를 모두 제공하는 Spring MVC 애플리케이션에 쉽게 통합할 수 있습니다. 또한 WebSocketHttpRequestHandler를 호출하여 다른 HTTP 처리 시나리오에 쉽게 통합할 수 있습니다. 이는 편리하고 이해하기 쉽습니다. 그러나 JSR-356 runtime과 관련하여 특별한 고려 사항이 적용됩니다.
Jakarta WebSocket API(JSR-356)는 두 가지 deployment mechanism을 제공합니다. 첫 번째는 startup 시 Servlet 컨테이너 classpath scan(Servlet 3 기능)을 포함합니다. 다른 하나는 Servlet 컨테이너 초기화 시 사용할 registration API입니다. 이러한 mechanism 중 어느 것도 WebSocket 핸드셰이크와 모든 다른 HTTP 요청를 포함한 모든 HTTP 처리에 대해 Spring MVC의 DispatcherServlet과 같은 단일 “front controller”를 사용할 수 있게 하지는 않습니다.
이는 WebSocket API 2.1+ runtime에서 실행될 때 standard RequestUpgradeStrategy 구현으로 Spring의 WebSocket 지원가 해결하는 JSR-356의 중요한 제한 사항입니다.
두 번째 고려 사항은 JSR-356 지원가 있는 Servlet 컨테이너가 애플리케이션 startup을 느리게(경우에 따라 극적으로) 만들 수 있는 ServletContainerInitializer(SCI) scan을 수행할 것으로 예상된다는 점입니다. JSR-356 지원가 있는 Servlet 컨테이너 버전으로 upgrade한 후 상당한 영향이 관찰되면, 다음 예제와 같이 web.xml에서 <absolute-ordering /> element를 사용하여 web fragment(SCI scanning 포함)를 선택적으로 활성화하거나 비활성화할 수 있어야 합니다:
1<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation=" 4 https://jakarta.ee/xml/ns/jakartaee 5 https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" 6 version="5.0"> 7 8 <absolute-ordering/> 9 10</web-app>
그런 다음 Servlet 3 Java initialization API에 대한 지원를 제공하는 Spring 자체의 SpringServletContainerInitializer와 같이 이름으로 web fragment를 선택적으로 활성화할 수 있습니다. 다음 예제는 이를 수행하는 방법을 보여줍니다:
1<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation=" 4 https://jakarta.ee/xml/ns/jakartaee 5 https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" 6 version="5.0"> 7 8 <absolute-ordering> 9 <name>spring_web</name> 10 </absolute-ordering> 11 12</web-app>
See equivalent in the Reactive stack
input 메시지 버퍼 크기, idle timeout 등과 같은 underlying WebSocket 서버를 설정할 수 있습니다.
Jakarta WebSocket 서버의 경우, 설정에 ServletServerContainerFactoryBean을 추가할 수 있습니다. 예를 들면 다음과 같습니다:
1@Configuration 2public class WebSocketConfiguration { 3 4 @Bean 5 public ServletServerContainerFactoryBean createWebSocketContainer() { 6 ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean(); 7 container.setMaxTextMessageBufferSize(8192); 8 container.setMaxBinaryMessageBufferSize(8192); 9 return container; 10 } 11}
1@Configuration 2class WebSocketConfiguration { 3 4 @Bean 5 fun createWebSocketContainer() = ServletServerContainerFactoryBean().apply { 6 maxTextMessageBufferSize = 8192 7 maxBinaryMessageBufferSize = 8192 8 } 9}
1<bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean"> 2 <property name="maxTextMessageBufferSize" value="8192"/> 3 <property name="maxBinaryMessageBufferSize" value="8192"/> 4</bean>
client Jakarta WebSocket 설정의 경우, 프로그래매틱 설정에서는<br>ContainerProvider.getWebSocketContainer()를 사용하거나 XML에서는<br>
WebSocketContainerFactoryBean을 사용하십시오.
Jetty의 경우, WebSocket 서버를 설정하기 위한 callback을 제공할 수 있습니다:
1@Configuration 2@EnableWebSocket 3public class JettyWebSocketConfiguration implements WebSocketConfigurer { 4 5 @Override 6 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 7 registry.addHandler(echoWebSocketHandler(), "/echo").setHandshakeHandler(handshakeHandler()); 8 } 9 10 @Bean 11 public WebSocketHandler echoWebSocketHandler() { 12 return new MyEchoHandler(); 13 } 14 15 @Bean 16 public DefaultHandshakeHandler handshakeHandler() { 17 JettyRequestUpgradeStrategy strategy = new JettyRequestUpgradeStrategy(); 18 strategy.addWebSocketConfigurer(configurable -> { 19 configurable.setInputBufferSize(8192); 20 configurable.setIdleTimeout(Duration.ofSeconds(600)); 21 }); 22 return new DefaultHandshakeHandler(strategy); 23 } 24}
1@Configuration 2@EnableWebSocket 3class JettyWebSocketConfiguration : WebSocketConfigurer { 4 5 override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { 6 registry.addHandler(echoWebSocketHandler(), "/echo").setHandshakeHandler(handshakeHandler()) 7 } 8 9 @Bean 10 fun echoWebSocketHandler(): WebSocketHandler { 11 return MyEchoHandler() 12 } 13 14 @Bean 15 fun handshakeHandler(): DefaultHandshakeHandler { 16 val strategy = JettyRequestUpgradeStrategy() 17 strategy.addWebSocketConfigurer { 18 it.inputBufferSize = 8192 19 it.idleTimeout = Duration.ofSeconds(600) 20 } 21 return DefaultHandshakeHandler(strategy) 22 } 23}
WebSocket 위에서 STOMP를 사용할 때는<br>STOMP WebSocket transport<br>property도 설정해야 합니다.
See equivalent in the Reactive stack
Spring Framework 4.1.5부터 WebSocket 및 SockJS의 기본 동작은 동일 origin 요청만 허용하는 것입니다. 모든 origin 또는 지정된 origin 목록을 허용하는 것도 가능합니다. 이 check는 주로 browser client를 위해 설계되었습니다. 다른 유형의 client가 Origin header 값을 수정하는 것을 막는 것은 없습니다(자세한 내용은 RFC 6454: The Web Origin Concept을 참조하십시오).
가능한 세 가지 동작은 다음과 같습니다:
X-Frame-Options가 SAMEORIGIN으로 설정되고, 요청의 origin을 확인할 수 없기 때문에 JSONP transport는 비활성화됩니다. 그 결과, 이 모드가 활성화되면 IE6 및 IE7은 지원되지 않습니다.http:// 또는 https://로 시작해야 합니다. 이 모드에서 SockJS가 활성화되면 IFrame transport가 비활성화됩니다. 그 결과, 이 모드가 활성화되면 IE6부터 IE9까지는 지원되지 않습니다.*를 제공해야 합니다. 이 모드에서는 모든 transport를 사용할 수 있습니다.다음 예제와 같이 WebSocket 및 SockJS allowed origin을 설정할 수 있습니다:
1@Configuration 2@EnableWebSocket 3public class WebSocketConfiguration implements WebSocketConfigurer { 4 5 @Override 6 public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { 7 registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com"); 8 } 9 10 @Bean 11 public WebSocketHandler myHandler() { 12 return new MyHandler(); 13 } 14}
1@Configuration 2@EnableWebSocket 3class WebSocketConfiguration : WebSocketConfigurer { 4 5 override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) { 6 registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("https://mydomain.com") 7 } 8 9 @Bean 10 fun myHandler(): WebSocketHandler { 11 return MyHandler() 12 } 13}
1<beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:websocket="http://www.springframework.org/schema/websocket" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 https://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/websocket 8 https://www.springframework.org/schema/websocket/spring-websocket.xsd"> 9 10 <websocket:handlers allowed-origins="https://mydomain.com"> 11 <websocket:mapping path="/myHandler" handler="myHandler" /> 12 </websocket:handlers> 13 14 <bean id="myHandler" class="org.springframework.docs.web.websocket.websocketserverhandler.MyHandler" /> 15 16</beans>
WebSockets
SockJS Fallback