websocket 实现后端主动前端推送数据、及时通讯(vue3 + springboot)

实现WebSocket后端主动向前端推送数据以及即时通讯,可以使用Vue 3作为前端框架,Spring Boot作为后端框架。以下是一个基本的实现步骤和示例代码。

图片[1]_websocket 实现后端主动前端推送数据、及时通讯(vue3 + springboot)_知途无界

后端(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
      @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("*");  
          }  
      }
      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;
        @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();  
                        }  
                    }  
                }  
            }  
        }
        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;
          @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!";  
              }  
          }
          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
              喜欢就点个赞,支持一下吧!
              点赞85 分享
              So what if we fall down? At least we are still young.
              摔倒了又怎样,至少我们还年轻
              评论 抢沙发
              头像
              欢迎您留下评论!
              提交
              头像

              昵称

              取消
              昵称表情代码图片

                暂无评论内容