当我们使用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
* 邮箱: kmustchang@qq.com
* 功能: 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.
通过上面的配置就可以收到心跳了
更多精彩内容:请关注公众号: