天天看点

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.

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

继续阅读