实现WebSocket后端主动向前端推送数据以及即时通讯,可以使用Vue 3作为前端框架,Spring Boot作为后端框架。以下是一个基本的实现步骤和示例代码。
![图片[1]_websocket 实现后端主动前端推送数据、及时通讯(vue3 + springboot)_知途无界](https://zhituwujie.com/wp-content/uploads/2024/10/d2b5ca33bd20241010103437.png)
后端(Spring Boot)
添加依赖:
在Spring Boot项目的pom.xml
中添加WebSocket相关的依赖。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
配置WebSocket:
创建一个配置类来注册WebSocket端点。
import org.springframework.context.annotation.Configuration;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {private final MyWebSocketHandler webSocketHandler;public WebSocketConfig(MyWebSocketHandler webSocketHandler) {this.webSocketHandler = webSocketHandler;}@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(webSocketHandler, "/ws").setAllowedOrigins("*");}}import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final MyWebSocketHandler webSocketHandler; public WebSocketConfig(MyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/ws").setAllowedOrigins("*"); } }import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { private final MyWebSocketHandler webSocketHandler; public WebSocketConfig(MyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler, "/ws").setAllowedOrigins("*"); } }
创建WebSocket处理器:
处理WebSocket连接、消息和错误。
import org.springframework.stereotype.Component;import org.springframework.web.socket.*;import org.springframework.web.socket.handler.TextWebSocketHandler;import java.util.concurrent.CopyOnWriteArraySet;@Componentpublic class MyWebSocketHandler extends TextWebSocketHandler {private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>();@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {sessions.add(session);System.out.println("New connection established: " + session.getId());}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {// 处理来自客户端的消息System.out.println("Received message: " + message.getPayload());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {sessions.remove(session);System.out.println("Connection closed: " + session.getId());}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {System.err.println("Transport error: " + exception.getMessage());}public void sendMessageToAll(String message) {for (WebSocketSession session : sessions) {if (session.isOpen()) {try {session.sendMessage(new TextMessage(message));} catch (Exception e) {e.printStackTrace();}}}}}import org.springframework.stereotype.Component; import org.springframework.web.socket.*; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.concurrent.CopyOnWriteArraySet; @Component public class MyWebSocketHandler extends TextWebSocketHandler { private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); System.out.println("New connection established: " + session.getId()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理来自客户端的消息 System.out.println("Received message: " + message.getPayload()); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); System.out.println("Connection closed: " + session.getId()); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { System.err.println("Transport error: " + exception.getMessage()); } public void sendMessageToAll(String message) { for (WebSocketSession session : sessions) { if (session.isOpen()) { try { session.sendMessage(new TextMessage(message)); } catch (Exception e) { e.printStackTrace(); } } } } }import org.springframework.stereotype.Component; import org.springframework.web.socket.*; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.concurrent.CopyOnWriteArraySet; @Component public class MyWebSocketHandler extends TextWebSocketHandler { private final CopyOnWriteArraySet<WebSocketSession> sessions = new CopyOnWriteArraySet<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); System.out.println("New connection established: " + session.getId()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理来自客户端的消息 System.out.println("Received message: " + message.getPayload()); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); System.out.println("Connection closed: " + session.getId()); } @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { System.err.println("Transport error: " + exception.getMessage()); } public void sendMessageToAll(String message) { for (WebSocketSession session : sessions) { if (session.isOpen()) { try { session.sendMessage(new TextMessage(message)); } catch (Exception e) { e.printStackTrace(); } } } } }
在控制器中使用WebSocket处理器:
你可以通过注入MyWebSocketHandler
来在其他地方(如控制器)发送消息。
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class WebSocketController {private final MyWebSocketHandler webSocketHandler;@Autowiredpublic WebSocketController(MyWebSocketHandler webSocketHandler) {this.webSocketHandler = webSocketHandler;}@GetMapping("/send")public String sendMessage(@RequestParam String message) {webSocketHandler.sendMessageToAll(message);return "Message sent!";}}import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class WebSocketController { private final MyWebSocketHandler webSocketHandler; @Autowired public WebSocketController(MyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @GetMapping("/send") public String sendMessage(@RequestParam String message) { webSocketHandler.sendMessageToAll(message); return "Message sent!"; } }import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class WebSocketController { private final MyWebSocketHandler webSocketHandler; @Autowired public WebSocketController(MyWebSocketHandler webSocketHandler) { this.webSocketHandler = webSocketHandler; } @GetMapping("/send") public String sendMessage(@RequestParam String message) { webSocketHandler.sendMessageToAll(message); return "Message sent!"; } }
前端(Vue 3)
安装WebSocket库(可选):
虽然Vue 3本身不需要额外的库来使用WebSocket,但你可以使用如reconnecting-websocket
这样的库来处理重连等复杂情况。
创建WebSocket连接:
在Vue组件中创建WebSocket连接,并处理消息和连接事件。
<template><div><h1>WebSocket Demo</h1><ul><li v-for="message in messages" :key="message">{{ message }}</li></ul></div></template><script>export default {data() {return {socket: null,messages: []};},mounted() {this.connectWebSocket();},methods: {connectWebSocket() {this.socket = new WebSocket('ws://localhost:8080/ws');this.socket.onopen = () => {console.log('WebSocket connection opened');};this.socket.onmessage = (event) => {this.messages.push(event.data);};this.socket.onclose = () => {console.log('WebSocket connection closed');// Optionally, try to reconnect here};this.socket.onerror = (error) => {console.error('WebSocket error:', error);};}},beforeUnmount() {if (this.socket) {this.socket.close();}}};</script><style scoped>/* Add your styles here */</style><template> <div> <h1>WebSocket Demo</h1> <ul> <li v-for="message in messages" :key="message">{{ message }}</li> </ul> </div> </template> <script> export default { data() { return { socket: null, messages: [] }; }, mounted() { this.connectWebSocket(); }, methods: { connectWebSocket() { this.socket = new WebSocket('ws://localhost:8080/ws'); this.socket.onopen = () => { console.log('WebSocket connection opened'); }; this.socket.onmessage = (event) => { this.messages.push(event.data); }; this.socket.onclose = () => { console.log('WebSocket connection closed'); // Optionally, try to reconnect here }; this.socket.onerror = (error) => { console.error('WebSocket error:', error); }; } }, beforeUnmount() { if (this.socket) { this.socket.close(); } } }; </script> <style scoped> /* Add your styles here */ </style><template> <div> <h1>WebSocket Demo</h1> <ul> <li v-for="message in messages" :key="message">{{ message }}</li> </ul> </div> </template> <script> export default { data() { return { socket: null, messages: [] }; }, mounted() { this.connectWebSocket(); }, methods: { connectWebSocket() { this.socket = new WebSocket('ws://localhost:8080/ws'); this.socket.onopen = () => { console.log('WebSocket connection opened'); }; this.socket.onmessage = (event) => { this.messages.push(event.data); }; this.socket.onclose = () => { console.log('WebSocket connection closed'); // Optionally, try to reconnect here }; this.socket.onerror = (error) => { console.error('WebSocket error:', error); }; } }, beforeUnmount() { if (this.socket) { this.socket.close(); } } }; </script> <style scoped> /* Add your styles here */ </style>
发送消息(可选):
你可以添加一个表单来发送消息到后端,后端再通过WebSocket广播给所有连接的客户端。
<!-- 在模板中添加表单 --><template><div><h1>WebSocket Demo</h1><form @submit.prevent="sendMessage"><input v-model="newMessage" placeholder="Type a message" /><button type="submit">Send</button></form><ul><li v-for="message in messages" :key="message">{{ message }}</li></ul></div></template><script>export default {data() {return {socket: null,messages: [],newMessage: ''};},mounted() {this.connectWebSocket();},methods: {connectWebSocket() {// ...(与之前相同)},sendMessage() {if (this.socket && this.socket.readyState === WebSocket.OPEN) {this.socket.send(this.newMessage);this.newMessage = ''; // Clear the input field} else {console.error('WebSocket is not open');}}},beforeUnmount() {// ...(与之前相同)}};</script><!-- 在模板中添加表单 --> <template> <div> <h1>WebSocket Demo</h1> <form @submit.prevent="sendMessage"> <input v-model="newMessage" placeholder="Type a message" /> <button type="submit">Send</button> </form> <ul> <li v-for="message in messages" :key="message">{{ message }}</li> </ul> </div> </template> <script> export default { data() { return { socket: null, messages: [], newMessage: '' }; }, mounted() { this.connectWebSocket(); }, methods: { connectWebSocket() { // ...(与之前相同) }, sendMessage() { if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(this.newMessage); this.newMessage = ''; // Clear the input field } else { console.error('WebSocket is not open'); } } }, beforeUnmount() { // ...(与之前相同) } }; </script><!-- 在模板中添加表单 --> <template> <div> <h1>WebSocket Demo</h1> <form @submit.prevent="sendMessage"> <input v-model="newMessage" placeholder="Type a message" /> <button type="submit">Send</button> </form> <ul> <li v-for="message in messages" :key="message">{{ message }}</li> </ul> </div> </template> <script> export default { data() { return { socket: null, messages: [], newMessage: '' }; }, mounted() { this.connectWebSocket(); }, methods: { connectWebSocket() { // ...(与之前相同) }, sendMessage() { if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(this.newMessage); this.newMessage = ''; // Clear the input field } else { console.error('WebSocket is not open'); } } }, beforeUnmount() { // ...(与之前相同) } }; </script>
注意事项
- 确保WebSocket服务器和客户端的URL匹配。
- 处理WebSocket连接的安全性问题,如使用WSS(WebSocket Secure)而不是WS。
- 在生产环境中,考虑添加错误处理、重连逻辑和消息格式验证。
- 如果你的应用需要支持多用户、多房间或复杂的消息传递逻辑,你可能需要更复杂的后端架构,如使用消息队列或实时数据库。
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END
暂无评论内容