染指余忆 2024-04-14 16:17 采纳率: 96.3%
浏览 26
已结题

使用vue3 和Springboot 通过 websocket实现前后端通信

以下代码是使用vue3 和Springboot 通过 websocket实现前后端通信,但是失败,请指出错误原因并且更正代码


<script setup>
import {ref} from "vue";

const message=ref()
let socket;
socket = new WebSocket("ws/webSocket");
socket.onopen = function(event) {
  console.log(event.data);
};
socket.onmessage = function(event) {
  console.log(event.data);
};
socket.onerror = function(error) {
  console.log("WebSocket Error: " + error);
}

function senMessage() {
  if (socket.readyState===1) {
    socket.send(message)
  }

}
</script>

<template>
  <div class="MyBody1">
    <input type="text" v-model="message">
    <button @click="senMessage">sent</button>
  </div>
</template>

<style scoped>

</style>
devServer:{
    allowedHosts: "all",
    proxy: {
      '/spring': {
        target: 'http://localhost:8081',
        changeOrigin: true,
        pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'""代替
          '^/spring': ""
        }
      },

      '/ws': {
        target: 'ws://http://localhost:8081',
        ws: true,
        changeOrigin: true,
        // logLevel: 'debug' // 可选,用于调试代理连接
        pathRewrite: { // pathRewrite 的作用是把实际Request Url中的'/api'""代替
          '^/ws': ""
        }
      },
    },
  },

package org.example.halospring.HaloSpring.Service.WebsocketService;


import jakarta.servlet.http.HttpSession;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@ServerEndpoint("/webSocket")
public class WebsocketImple {
    public static int number=0;
    @OnOpen
    public void onOpen(Session session, HttpSession httpSession) throws IOException {
            number++;
            System.out.println("第"+number+"个用户登录");
            session.getAsyncRemote().sendText("第"+number+"个用户登录");
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println(message);
    }

    @OnClose
    public void onClose(Session session) {
        session.getAsyncRemote().sendText("关闭");
        number--;
        System.out.println("用户关闭");
    }

    @OnError
    public void onError(Throwable error) {
        System.err.println("WebSocket Error: " + error);
    }
}

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-14 16:17
    关注

    引自免费微信小程序:皆我百晓生

    首先,让我们逐个分析您的代码并找出可能的问题。

    1. Vue3 部分:

      • onopen事件处理函数中,您尝试打印event.data,但在WebSocket连接打开时,通常不会发送数据。您可以将这段代码移除,或者更改为您期望在连接成功后发送的消息。
    2. Vue3 部分(修复后的代码):

    <script setup>
    import { ref } from "vue";
    
    const message = ref("");
    let socket;
    socket = new WebSocket("ws/spring/ws/webSocket"); // 使用正确的路径
    socket.onopen = function (event) {
      console.log("Connection opened");
    };
    socket.onmessage = function (event) {
      console.log(event.data);
    };
    socket.onerror = function (error) {
      console.error("WebSocket Error: ", error);
    };
    
    function sendMessage() {
      if (socket.readyState === 1) {
        socket.send(message.value); // 发送message的值
      }
    }
    </script>
    
    <template>
      <div class="MyBody1">
        <input type="text" v-model="message">
        <button @click="sendMessage">Send</button>
      </div>
    </template>
    
    <style scoped></style>
    
    1. Spring Boot 部分:

      • 您的WebSocket服务器配置看起来没有问题,但为了确保与Vue3应用正确连接,确认一下端口和URL是否匹配。同时,建议使用Spring Boot的WebSocket支持来创建WebSocket服务,而不是手动实现WebSocket接口。这将使代码更加简洁且易于维护。
    2. Spring Boot 部分(修复后的代码):

    import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.handler.annotation.SendTo;
    import org.springframework.stereotype.Component;
    
    @Component
    public class WebSocketController {
    
        private static AtomicInteger counter = new AtomicInteger();
    
        @MessageMapping("/ws/webSocket") // 对应前端的URL
        @SendTo("/topic/messages") // 前端会订阅这个主题
        public String handleMessage(String message) {
            int count = counter.incrementAndGet();
            return "第" + count + "个用户发送: " + message;
        }
    }
    
    1. 配置Spring Boot应用以启用WebSocket支持: 在您的主配置类上添加@EnableWebSocketMessageBroker注解,并定义一个简单的消息代理。
    import 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;
    
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableSimpleBroker("/topic");
            config.setApplicationDestinationPrefixes("/app");
        }
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/ws/webSocket").withSockJS();
        }
    }
    
    1. 最后,在前端的Vue3项目中,您应该使用sockjs-client库来连接到WebSocket服务器。这是对main.js进行修改的示例:
    import { createApp } from 'vue'
    import App from './App.vue'
    
    // 引入sockjs-client库
    import SockJS from 'sockjs-client';
    import Stomp from 'stompjs';
    
    createApp(App).mount('#app')
    
    const socket = new SockJS('/spring/ws/webSocket');
    const stompClient = Stomp.over(socket);
    
    stompClient.connect({}, function(frame) {
      console.log('Connected: ' + frame);
      stompClient.subscribe('/topic/messages', function(message) {
        console.log(JSON.parse(message.body));
      });
    });
    

    这样,当您在前端输入文本并点击发送按钮时,消息应该能通过WebSocket传递到Spring Boot服务器,然后广播给所有客户端。同样,当其他客户端发送消息时,前端也会接收到这些消息。注意,上述代码仅作为示例,可能需要根据您的具体需求进行调整。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 9月18日
  • 已采纳回答 9月10日
  • 创建了问题 4月14日

悬赏问题

  • ¥15 app:debugCompileClasspath'.
  • ¥20 公众号如何实现点击超链接后自动发送文字
  • ¥15 用php隐藏类名和增加类名
  • ¥15 算法设计与分析课程的提问
  • ¥15 用MATLAB汇总拟合图
  • ¥15 智能除草机器人方案设计
  • ¥15 对接wps协作接口实现消息发送
  • ¥15 SQLite 出现“Database is locked” 如何解决?
  • ¥15 已经加了学校的隶属邮箱了,为什么还是进不去github education?😭
  • ¥15 求会做聚类,TCN的朋友有偿线上指导。以下是目前遇到的问题