(一)springboot结合websocket之使用STOMP协议推送消息

前言

有时候前端需要实时的获取后端的信息,比如订单的消息,发货之类的通知,实时的服务器信息,股票信息等。有一种方法是ajax轮训,就是间隔一段时间查询服务器一次,但是这种方式对服务器不太友好。所以,还有另一种方法,websocket。

一、引入websocket

pom文件引入依赖


    org.springframework.boot
    spring-boot-starter-websocket

二、配置

写一个配置类,继承AbstractWebSocketMessageBrokerConfigurer,这个类配置的是关于STOMP协议。前端使用的是stomp.js,关于stomp.js可以看一下这一篇博客:https://www.cnblogs.com/goloving/p/10746378.html 。stomp.js 具体的使用方法下面会写。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketStompConfig extends AbstractWebSocketMessageBrokerConfigurer {

	/**
     * 注册stomp的端点,发布或者订阅消息时需要连接此端点
     */
	@Override
	public void registerStompEndpoints(StompEndpointRegistry registry) {
		registry.addEndpoint("/endpoint").setAllowedOrigins("*").withSockJS();
		
	}
	
	/**
     * 配置信息代理(中介转发)
     */
	@Override
	public void configureMessageBroker(MessageBrokerRegistry registry) {
		
		// 订阅Broker名称
		registry.enableSimpleBroker("/queue","/topic","/chat");
		// 全局使用的消息前缀(客户端订阅路径上会体现出来)
		registry.setApplicationDestinationPrefixes("/app");
		
	}
	
}

三、使用

首先定义两个传输数据的对象

public class InMessage {
	
	private String from;
	
	private String to;
	
	private LocalDateTime time = LocalDateTime.now();
	
	private String content;
    
    //省略setter和getter
}
public class OutMessage {
	
	private String from;
	
	private LocalDateTime time = LocalDateTime.now();
	
	private String content;
    
    //省略setter和getter
}

使用起来也是很简单,有两种方法。

1、使用@SendTo注解来转发数据

value属性值的第一值 /topic 必须在enableSimpleBroker中配置,@MessageMapping和@RequestMapping的作用类似。

@Controller
public class GameInfoController {

	@MessageMapping("/v1/game_chat")
	@SendTo("/topic/game_chat")
	public OutMessage gameInfo(InMessage message){
		
		return new OutMessage("",message.getContent());
	}
	
}

2、注入SimpMessagingTemplate推送消息

destination的第一个值必须在上面 的enableSimpleBroker中配置,与@SendTo的value使用方法一致。

@Component
public class WebSocketService {

	@Autowired
	private SimpMessagingTemplate template;
	
	public void sengTextMsg(String destination,Object message){
		
		template.convertAndSend(destination,message);
		
	}

}
@Controller
public class GameInfoV2Controller {
	
	@Autowired
	private WebSocketService webSocketService;
	
	@MessageMapping("/v2/chat")
	public void gameInfo(InMessage message){
		
		webSocketService.sendTopicMessage("/topic/game_rank", message);
	}
	
}

这两种方法的主要区别在于@SendTo的路径是写死的,SimpMessagingTemplate的路径可以动态设置。

3、给特定的人推送消息

以上都是群发消息,我们可以在路径上绑定id信息,这样就可以给特定的人推送消息了。在WebSocketService 中添加以下方法。

	public void sendChatMessage(InMessage message) {

		template.convertAndSend("/chat/single/"+message.getTo(),new OutMessage(message.getFrom(),message.getContent()));
		
	}
@Controller
public class ChatRoomV3Controller {

	@Autowired
	private WebSocketService webSocketService;
	
	@MessageMapping("v3/single/chat")
	public void singleChat(InMessage message){
		
		webSocketService.sendChatMessage(message);
		
	}
	
}

4、实时数据推送

我们可以使用@Scheduled注解来实现实时的数据推送,先在启用类上添加@EnableScheduling注解

再添加一个方法

	public void sendServerInfo() {
		
		DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime now = LocalDateTime.now();
		
		template.convertAndSend("/topic/server_info",new OutMessage(now.format(df)));
		
	}

然后直接使用@Scheduled注解一个方法就可以了,每秒推送一次数据

@Controller
public class ServerInfoV4Controller {
	
	@Autowired
	private WebSocketService webSocketService;
	
	@Scheduled(fixedRate = 1000)
	public void sendServerInfo(){
		
		webSocketService.sendServerInfo();
		
	}

}

四、stomp.js 的使用

使用起来也是挺简单的。看注释应该就明白了。要注意的是 subscribe的地址在后台要有,也就是和@SendTo、destination的值对应。



  
	
	Insert title here
	
	
	
	
	
	
	

  

	
	
	

写在后面的话

还有基于H5的websocket,后面会再写

你可能感兴趣的:(springboot,websocket)