2016-08-30 1 views
7

우리는 우리가 CONNECT 프레임을 전달하는 것을 WebSocket을 연결을 통해 봄이 : 핸들러가 인정봄 STOMP WebSocket을 통해 예약하지 하트 비트

CONNECT\naccept-version:1.2\nheart-beat:10000,10000\n\n\u0000 

는 새로운 세션을 시작하고,가 리턴 :

CONNECTED 
version:1.2 
heart-beat:0,0 

그러나 우리는 WebSocket을 열어 둘 수 있도록 심장 박동을 원합니다. 우리는 이 아니며 SockJS를 사용하는이 아닙니다. 그것은 브로커가 인증 한 후, 메모리 주소 참고로 simpHeartbeat=[[email protected], simpSessionId=46e855c9}]

모양을 설정가 heart-beat (기본 헤더)를 취득 후

StompHeaderAccessor [headers={simpMessageType=CONNECT, stompCommand=CONNECT, nativeHeaders={accept-version=[1.2], heart-beat=[5000,0]}, simpSessionAttributes={}, simpHeartbeat=[[email protected], simpSessionId=46e855c9}] 

:

나는 봄 메시지 처리기를 통해 강화 :

Processing CONNECT session=46e855c9 (여기서 sessionId는 simpSessionId와 다릅니다)?

이전에 TRACE 디버깅을 실행 중일 때 "스케줄링 하트 비트 ..."또는 그 효과가 나타났습니다 ... 지금은 보이지 않지만?

어떤 일이 벌어지고 있는지 알 수 있습니까? 하트 비트를 보내는 데 사용되는 SockJS 작업 스케줄러의 스레드 풀에서

SockJS 작업 스케줄러 통계 :

감사

은 내가 documentation의 설명을 발견했다. 하트 비트 이 STOMP 레벨에서 협상되면 SockJS 하트 비트가 사용 불가능합니다.

SockJS 하트 비트가 STOMP 하트 비트와 다른가요?

답변

5

예 SockJS 하트 비트가 다릅니다. 근본적으로 SockJS 프로토콜에서의 동일한 목적이나 목적은 연결이 "죽은"것처럼 보이지 않게하여 프록시가 사전에 그것을 닫을 수있게하는 것입니다. 보다 일반적으로 하트 비트는 각 측면에서 연결 문제를 사전에 감지하고 리소스를 정리할 수 있습니다.

전송 계층에서 STOMP 및 SockJS를 사용할 때 STOMP 하트 비트가 사용중인 경우 SockJS 하트 비트가 해제되는 이유는 둘 다 가질 필요가 없습니다. 그러나 여기 SockJS를 사용하지 않습니다.

구성을 표시하지는 않지만 자동으로 하트 비트를 보내지 않는 기본 제공 단순 브로커를 사용하고있는 것 같습니다. 구성 할 때 하트 비트를 사용 가능하게하는 옵션이 표시되며 태스크 스케줄러도 설정해야합니다.

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { 

    @Override 
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
     // ... 
    } 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry registry) { 
     registry.enableStompBrokerRelay(...) 
       .setTaskScheduler(...) 
       .setHeartbeat(...); 
    } 

} 
+4

@Rossen에 "내장형 단순 브로커를 사용하고 있다고 추측해도".enableStompBrokerRelay (...)를 쓰려고하십니까? '.enableSimpleBroker (...) '처럼 보이지, 그렇지? –

4

스프링 4.2 당신이 SockJS을 통해 스톰프를 사용하여 하트 비트 협상 결과의 서버 측에서 완벽하게 제어 할 수있는 내장 SimpleBroker :

public class WebSocketConfigurer extends AbstractWebSocketMessageBrokerConfigurer { 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry config) { 
     ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler(); 
     te.setPoolSize(1); 
     te.setThreadNamePrefix("wss-heartbeat-thread-"); 
     te.initialize(); 

     config.enableSimpleBroker("/") 
       /** 
       * Configure the value for the heartbeat settings. The first number 
       * represents how often the server will write or send a heartbeat. 
       * The second is how often the client should write. 0 means no heartbeats. 
       * <p>By default this is set to "0, 0" unless the {@link #setTaskScheduler 
       * taskScheduler} in which case the default becomes "10000,10000" 
       * (in milliseconds). 
       * @since 4.2 
       */ 
       .setHeartbeatValue(new long[]{heartbeatServer, heartbeatClient}) 
       .setTaskScheduler(te); 
    } 

    @Override 
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
     registry.addEndpoint(.....) 
       .setAllowedOrigins(....) 
       .withSockJS(); 
    } 
} 
+0

신난다, 그것은 내가 어디에서도 발견 할 수없는 essantial 한 무엇인가이다! 고마워요! – thorinkor

+0

다행이 당신을 도왔습니다! – artemisian

5

우리 봄, WebSocket을, STOMP 봄 세션과 같은 문제가있어 - 아니 heartbeats 및 Spring 세션은 websocket이 서버 측에서 메시지를받지 않는 동안 만료 될 수 있습니다. 우리는 20000ms마다 브라우저에서 STOMP 하트 비트를 활성화하고 SimpMessageType.HEARTBEATsessionRepositoryInterceptor과 일치 시켜서 메시지없이 STOMP 하트 비트에서 Spring 세션의 마지막 액세스 시간을 업데이트하도록 유지합니다. 우리는 추상 세션 WebSocketMessageBrokerConfigurer을 사용하여 빌드 중 스프링 세션과 websocket 세션 바인딩을 활성화해야했습니다. Spring manual, 예. 공식 예제에서는 스프링 세션이 인바운드 websocket CONNECT/MESSAGE/SUBSCRIBE/UNSUBSCRIBE 메시지에서 업데이트되지만 하트 비트가 아니므로 2 가지를 다시 구성해야합니다. 적어도 인바운드 하트 비트를 활성화하고 Spring 세션을 websocket 하트 비트에 반응하도록 조정하십시오

public class WebSocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<ExpiringSession> { 

    @Autowired 
    SessionRepositoryMessageInterceptor sessionRepositoryInterceptor; 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry config) { 
     sessionRepositoryInterceptor.setMatchingMessageTypes(EnumSet.of(SimpMessageType.CONNECT, 
       SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, 
       SimpMessageType.UNSUBSCRIBE, SimpMessageType.HEARTBEAT)); 

     config.setApplicationDestinationPrefixes(...); 
     config.enableSimpleBroker(...) 
      .setTaskScheduler(new DefaultManagedTaskScheduler()) 
      .setHeartbeatValue(new long[]{0,20000}); 
    } 
} 

우리가 시도하는 또 다른 방법은 아웃 바운드 웹 소켓 메시지에 봄 세션에게 마지막 액세스 시간을 업데이트 플러스 청취자를 통해 웹 소켓 세션 -> 봄 세션 맵을 유지하기 위해 약간의 재 구현 SessionRepositoryMessageInterceptor의 기능이지만, 위의 코드는 한 속임수.

관련 문제