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

這樣的話,用戶端每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);這句話就可以了。前一個是配置心跳,後一個使用一個線程發送心跳。
問題的解決位址: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.
通過上面的配置就可以收到心跳了