天天看點

Spring Boot通信之STOMP協定:背景不發送心跳的問題

當我們使用SockJS去連結背景伺服器時:可會收到CONNECTED幀(連接配接成功傳回的幀)中的:心跳是0,0。

Spring Boot通信之STOMP協定:背景不發送心跳的問題

這樣的話,用戶端每10秒都會向伺服器發送一個心跳幀,但是伺服器不會向用戶端發送心跳,因為伺服器配置的是0,0。表示不發送心跳。我們可以在Network頁籤(按F12打開Chrome浏覽器)中的幀看到:用戶端會發送心跳幀,而不會收到心跳幀。

解決方法:

在Spring Boot中的配置檔案中設定心跳:

package com.kmust.springboot_stomp_one.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * 作者: 常
 * 建立時間: 2018/6/29 17:50
 * 郵箱: [email protected]
 * 功能: websocket的配置檔案
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {


    private static long HEART_BEAT=5000;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //設定連接配接websocket的位址,       注意使用    “/項目名/ws-start”   進行連接配接websocket。
        //setAllowedOrigins("*")是設定所有請求都可以通路,即允許跨域的問題,或者自己設定允許通路的域名。
        //withSockJS()     在不支援websocket的浏覽器中,使用sockJs備選作為連接配接。
        registry.addEndpoint("/ws-start").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //設定簡單的消息代理器,它使用Memory(記憶體)作為消息代理器,
        //其中/user和/topic都是我們發送到前台的資料字首。前端必須訂閱以/user開始的消息(.subscribe()進行監聽)。
        //setHeartbeatValue設定背景向前台發送的心跳,
        //注意:setHeartbeatValue這個不能單獨設定,不然不起作用,要配合後面setTaskScheduler才可以生效。
        //對應的解決方法的網址:https://stackoverflow.com/questions/39220647/spring-stomp-over-websockets-not-scheduling-heartbeats
        ThreadPoolTaskScheduler te = new ThreadPoolTaskScheduler();
        te.setPoolSize(1);
        te.setThreadNamePrefix("wss-heartbeat-thread-");
        te.initialize();
        registry.enableSimpleBroker("/user","/topic").setHeartbeatValue(new long[]{HEART_BEAT,HEART_BEAT}).setTaskScheduler(te);;
        //設定我們前端發送:websocket請求的字首位址。即client.send("/ws-send")作為字首,然後再加上對應的@MessageMapping後面的位址
        registry.setApplicationDestinationPrefixes("/ws-send");
    }
}
           

我們隻要配置setHeartbeatValue(new long[]{HEART_BEAT,HEART_BEAT}).setTaskScheduler(te);這句話就可以了。前一個是配置心跳,後一個使用一個線程發送心跳。

Spring Boot通信之STOMP協定:背景不發送心跳的問題
Spring Boot通信之STOMP協定:背景不發送心跳的問題

問題的解決位址:https://stackoverflow.com/questions/39220647/spring-stomp-over-websockets-not-scheduling-heartbeats

下面解釋一下原因:當我們使用基于WebSocket/SockJS協定的STOMP時,如果STOMP用戶端與伺服器端要協商心跳交換的時候,SockJS的心跳就不起作用。

原始内容:When using STOMP over WebSocket/SockJS, if the STOMP client and server negotiate heartbeats to be exchanged, the SockJS heartbeats are disabled.

通過上面的配置就可以收到心跳了

繼續閱讀