Spring Boot通讯之STOMP协议:后台不发送心跳的问题

当咱们使用SockJS去连接后台服务器时:可会收到CONNECTED帧(链接成功返回的帧)中的:心跳是0,0。前端


这样的话,客户端每10秒都会向服务器发送一个心跳帧,可是服务器不会向客户端发送心跳,由于服务器配置的是0,0。表示不发送心跳。咱们能够在Network选项卡(按F12打开Chrome浏览器)中的帧看到:客户端会发送心跳帧,而不会收到心跳帧。java

解决方法:web

在Spring Boot中的配置文件中设置心跳:spring

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的心跳就不起做用。springboot

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

经过上面的配置就能够收到心跳了websocket