在这篇博客中,我将详细介绍如何使用 Spring Boot 整合 WebSocket,并实现消息推送功能。我们将使用 @EnableWebSocketMessageBroker
注解来配置 WebSocket,使用 SimpMessagingTemplate
发送消息。前端将使用 vue.min.js
、sockjs.min.js
和 stomp.min.js
实现与后端的通信。
首先,在 pom.xml
中添加所需的依赖:
xml<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- 其他依赖 -->
</dependencies>
或
gradledependencies { implementation 'org.springframework.boot:spring-boot-starter-websocket' // 其他依赖 }
创建一个 WebSocket 配置类,使用 @EnableWebSocketMessageBroker
注解:
javaimport org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
public final static String BASE_URL = "/topic";
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 注册的端点
registry.addEndpoint("/ws")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setPreservePublishOrder(true)
.enableSimpleBroker(BASE_URL);//订阅Broker名称
}
}
创建一个websocket发送消息工具类:
javaimport com.alibaba.fastjson.JSON;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Component;
@Component
public class WebSocketUtil {
private static SimpMessagingTemplate template;
public WebSocketUtil(SimpMessagingTemplate messagingTemplate) {
template = messagingTemplate;
}
/**
* 推送消息
*
* @param suffixUrl 路径后缀
* @param flag 标识
* @param msg 消息内容
*/
public static void sendMsg(String suffixUrl, String flag, Object msg) {
String path = BASE_URL + suffixUrl;
if (StrUtil.isNotBlank(flag)) {
path += "/" + flag;
}
template.convertAndSend(path, JSON.toJSONString(msg));
}
}
创建一个websocket消息控制器:
javaimport lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@CrossOrigin("*")
public class WebSocketController {
@MessageMapping("/toServer")
public void sendMsg(String msg, @Header("token") String token) {
log.info("请求接收到的消息为:{}", msg);
WebSocketUtil.sendMsg("/toClient", "1805473892329054222", "客户端你好!我是服务端");
}
}
前端我们使用 Vue.js 结合 SockJS 和 STOMP.js 实现 WebSocket 通信。首先,确保引入必要的库:
html<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1.4.0/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs@2.3.3/lib/stomp.min.js"></script>
工具封装
jsimport SockJS from 'sockjs-client'
import Stomp from 'stompjs'
import { getToken } from '@/utils/auth'
class WebSocketUtil {
constructor() {
this.socket = null;
this.broker = '/topic'
this.stompClient = null;
this.connected = false;
this.token = getToken()
this.headers = {
token: this.token
}
}
connect(callback) {
// 使用代理后的WebSocket URL
const socketUrl = "/business/ws"; // 代理配置会将/api/ws 转发到 http://127.0.0.1:23001/ws
this.socket = new SockJS(socketUrl);
this.stompClient = Stomp.over(this.socket);
this.stompClient.connect(this.headers, frame => {
this.connected = true
callback()
}, error => {
console.error('Error: ' + error);
});
}
subscribe(destination, callback) {
if (this.connected) {
this.stompClient.subscribe(this.broker + destination, (message) => {
callback(JSON.parse(message.body))
});
} else {
console.error('WebSocket is not connected, subscribe fail.');
}
}
connectAndSubscribe(destination, callback) {
// 使用代理后的WebSocket URL
const socketUrl = "/api/business/ws"; // 代理配置会将/api/ws 转发到 http://127.0.0.1:23001/ws
this.socket = new SockJS(socketUrl);
this.stompClient = Stomp.over(this.socket);
this.stompClient.connect(this.headers, frame => {
console.log('Connected: ' + frame);
this.connected = true
if (this.connected) {
this.stompClient.subscribe(this.broker + destination, message => {
callback(message);
});
} else {
console.error('WebSocket is not connected, subscribe fail.');
}
}, error => {
console.error('Error: ' + error);
});
}
send(destination, message) {
if (this.connected) {
this.stompClient.send(destination, this.headers, JSON.stringify(message))
} else {
console.error('WebSocket is not connected, send fail.');
}
}
disconnect() {
if (this.stompClient !== null) {
this.stompClient.disconnect();
}
this.connected = false;
console.log('Disconnected');
}
}
// 导出实例
export default new WebSocketUtil();
main.js全局配置
js// 工具类申明
import WebSocketUtil from '@/utils/websocket'
// 将 WebSocketUtil 实例添加到 Vue 原型上
Vue.prototype.$webSocketUtil = WebSocketUtil;
接下来,编写 Vue 组件来实现 WebSocket 通信:
html<div id="app">
<h1>WebSocket 测试</h1>
<div>
<label for="message">消息内容:</label>
<input type="text" v-model="message" id="message">
<button @click="sendMessage">发送消息</button>
</div>
<div>
<h2>收到的消息:</h2>
<ul>
<li v-for="msg in messages" :key="msg">{{ msg }}</li>
</ul>
</div>
</div>
<script>
export default {
data() {
return {
}
},
mounted() {
init()
},
methods: {
init() {
this.$webSocketUtil.connect(() => {
this.$webSocketUtil.subscribe('/toClient', (response) => {
console.log(response);
this.messages.push(response.body);
});
})
},
sendMessage() {
this.$webSocketUtil.send('/toServer', this.message)
}
}
}
</script>
以上就是使用 Spring Boot 整合 WebSocket 的完整示例。希望这篇教程对你有所帮助!