<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-websocketartifactId>
dependency>
package com.myself.computerThinking.Subscription;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Component
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
/**
* 用户可以订阅来自“/topic,/user”为前缀的消息
* 客户端只可以订阅这个前缀的主题
*/
registry.enableSimpleBroker("/topic","/user");
/**
* 客户端发送过来的消息,需要以“/app”为前缀,再通过Broker转发给响应的Controller
*/
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
/**
* 路径:"websocket/socketServer.action"被注册为STOMP端点,对外暴露,客户端通过该路径接入webScoket服务
*/
registry.addEndpoint("websocket/socketServer.action")
.setAllowedOrigins("*") //设置可以跨域请求
.withSockJS(); // 添加SockJS支持
}
}
withSockJS()
:添加SockJS的支持。(SockJS有关信息:https://blog.csdn.net/john_62/article/details/78208177)
SockJS是一个浏览器JavaScript库,它提供了一个类似于网络的对象。SockJS提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域通信通道。按浏览器是否支持WebSocket,以此使用三类传输对象:WebSocket
> HTTP流
> HTTP长轮询
var socket = new SockJS(url);
url为http、https开头var socket = new WebSocket(url);
url为ws、wss开头添加路径拦截器
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(myHandler(), "/myHandler").withSockJS();
}
@Bean
public WebSocketHandler myHandler() {
return new MyHandler();
}
package com.myself.computerThinking.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
super.addResourceHandlers(registry);
}
}
@Controller
public class subController {
@RequestMapping(value = "/stomp")
public String getStopm(){
return "stomp";
}
/**
* 接收前端发送消息: stompClient.send("/app/welcome", {atytopic:"greetings"}, "123");
* 并广播出去,广播地址为:/topic/CCC
* @param message
* @param topic
* @param headers
* @return
*/
@MessageMapping("/welcome")
@SendTo("/topic/CCC")
public String sendMessage(String message, @Header("atytopic")String topic, @Headers Map<String,Object> headers) {
System.out.println(topic);
System.out.println(headers);
System.out.println(message);
return message;
}
}
package com.myself.computerThinking.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class TaskServiceImpl implements TaskService {
private final static Logger logger= LoggerFactory.getLogger(TaskServiceImpl.class);
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;
@Scheduled(cron="0/10 * * * * ? ") //CRON表达式每10秒执行一次
@Override
public void selectCurDayDepotOrderInfo() {
logger.info("=====================AAA频道每10秒执行一次刷新=====================");
simpMessagingTemplate.convertAndSend("/topic/AAA","123");
}
@Scheduled(cron="0/13 * * * * ? ")
@Override
public void selectCustomerOrderInfo() {
logger.info("=====================BBB频道每13秒执行一次刷新=====================");
simpMessagingTemplate.convertAndSend("/topic/AAA", "456");
}
}
@Scheduled
,需要开启计时注解 @enablescheduling
@MessageMapping("/welcome")
接受前端传递 send的值,该页面要有@controller
注释@SendTo("/topic/CCC")
发送消息给订阅了CCC主题的前端
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>接受消息title>
head>
<body>
body>
<script src="/static/js/jquery.min.js">script>
<script src="/static/js/sockjs.min.js">script>
<script src="/static/js/stomp.js">script>
<script th:inline="javascript">
var url=getUrl();
console.log(url);
var socket = new SockJS(url); //WebSocket对应的地址
stompClient = Stomp.over(socket);
var headers={
username:'admin',
password:'admin'
};
stompClient.connect(headers, function (frame) {
console.log('Connected: ' + frame);
//订阅AAA频道
stompClient.subscribe('/topic/AAA', function (greeting) {
//后台传过来的json字符串转换为json对象
console.log("AAA"+greeting);
});
//订阅BBB频道
stompClient.subscribe('/topic/BBB', function (greeting) {
//后台传过来的json字符串转换为json对象
console.log("BBB"+greeting);
//处理并显示数据
});
//订阅BBB频道
stompClient.subscribe('/topic/CCC', function (greeting) {
//后台传过来的json字符串转换为json对象
console.log("CCC"+greeting);
//处理并显示数据
});
});
//获取项目路径
function getUrl() {
var strFullPath=window.document.location.href;
var strPath=window.document.location.pathname;
var pos=strFullPath.indexOf(strPath);
var prePath=strFullPath.substring(0,pos);
var postPath=strPath.substring(0,strPath.substr(1).indexOf('/')+1);
var basePath = prePath+postPath;
var url=basePath+"//websocket/socketServer.action";
return url
}
script>
html>