websocket实现订阅频道及定时推送对应频道数据

背景:主要是为了实现一个实时数据大屏,因为需要实时数据刷新,所以需要不停的从服务器获取数据库最新数据,最开始的想到是否可以前端使用定时器不断向服务器发送ajax请求数据,但这样的弊端便是会导致服务器的压力很大,所以后来在网上看到一个框架goeasy,一个实时的web消息推送服务,因为数据大屏对应不同的图表数据来源不同,而恰好goeasy又有可以订阅不同的频道,推送对应的消息,在这点的前提之下,我在后台再使用spring的定时器,就可对应频道推送对应数据,这样的实现效果挺好,但是他们的服务收费,虽然收费不高,不过后来觉得是否可以使用websocket来实现一个类似的功能,在网上了解到websocket_stomp可以实现订阅的功能,于是决定模范goeasy做一个类似的,订阅-发布功能,此记下记录。

声明:由于是做数据大屏不需要接收websocket消息只需要推送,所以这里没有接收websocket消息对应的代码

技术:websocket+stomp,spring schedule

========pom包导入========

        
        
            org.springframework
            spring-orm
            ${spring.version}
        

        
            org.springframework
            spring-websocket
            ${spring.version}
        
        
            org.springframework
            spring-messaging
            ${spring.version}
        

        

1.首先websoket的配置,使用注解方式

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;


/**
   * @author HeJD
   * @date 2018/9/3 16:58
   * @Description:WebSocket配置类
   */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
       /*
         * 用户可以订阅来自以"/topic"为前缀的消息,
         * 客户端只可以订阅这个前缀的主题
         */
        config.enableSimpleBroker("/topic");
        /*
         * 客户端发送过来的消息,需要以"/app"为前缀,再经过Broker转发给响应的Controller,
         * 我这里基本没用到,声明有说
         */
        config.setApplicationDestinationPrefixes("/app");

    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
         /*
          * 路径"/webSocketEndPoint"被注册为STOMP端点,对外暴露,客户端通过该路径接入WebSocket服务
          */
       registry.addEndpoint("websocket/socketServer.action");
    }

}

2.spring schedule的配置,使用注解的方式,applicationContext.xml中

2.1命名空间加入

xmlns:task="http://www.springframework.org/schema/task" 
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd

2.2启用注解驱动及定时器线程池

        
        
        

属性解释:pool-size,开启五个线程,spring schedule默认是单线程,开启5个线程可以让定时任务之间互不干扰,官网推荐1-10

3.使用定时器,开启定时任务

/**
 * @Auther: HeJD
 * @Date: 2018/8/29 17:18
 * @Description:
 */
@Component
public class TaskServiceImpl implements TaskService {

    private Logger log=Logger.getLogger(XgqTaskDepotServiceImpl.class);

    //取数据的Dao
    @Autowired
    private OrderMapper orderMapper;

    //这个就是我们可以指定频道推送对应数据的对象
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;


    @Scheduled(cron="0/10 * *  * * ? ")   //CRON表达式每10秒执行一次
    @Override
    public void selectCurDayDepotOrderInfo() {
        log.info("=====================AAA频道每10秒执行一次刷新=====================");
        List orderVoVoList = orderMapper.selectCurDayOrderInfo();
        EchartsVo echartsVo=this.assembleEchartsVo(orderVoVoList );
        simpMessagingTemplate.convertAndSend(Const.Channel.AAA_CHANNEL.getName(),echartsVo);
    }

    @Scheduled(cron="0/13 * *  * * ? ")
    @Override
    public void selectCustomerOrderInfo() {
        log.info("=====================BBB频道每13秒执行一次刷新=====================");
        List orderVoVoList =  orderMapper.selectCustomerOrderInfo();
        simpMessagingTemplate.convertAndSend(Const.Channel.BBB_CHANNEL.getName(), orderVoVoList);
    }
}

3.1,自定义频道的枚举常量,记录频道序号和频道名

/**
 * 全局常量类
 * @author HeJD
 * @date 2018年7月12日
 */
public class Const { 
   /**
	 * webSocket订阅频道枚举
	 */
	public enum Channel{

		AAA_CHANNEL(1,"/topic/AAA"),
		BBB_CHANNEL(2,"/topic/BBB");

		private final int code;
		private final String name;

		Channel(int code, String name) {
			this.code = code;
			this.name = name;
		}
		public String getName() {
			return name;
		}
	}
}

4.前端连接websokect并订阅频道

    
    
    
    
    

效果图如下:

结语:到这里websocket_stomp+定时器的功能就实现了,我使用的echarts显示数据,这里就不贴对应的代码了,只需要实现可以定时推送对应频道的数据到前端就好了,毕竟有了数据,前端显示数据根据前端框架或自己的需要即可。

推荐一篇参考文章:https://blog.csdn.net/elonpage/article/details/78446695?locationNum=5&fps=1

你可能感兴趣的:(spring)