vue3和springboot使用websocket通信

发布于:2025-02-11 ⋅ 阅读:(101) ⋅ 点赞:(0)

前端端口:9090

后端端口:8080

vue3

引入依赖:

npm install sockjs-client @stomp/stompjs

vue页面

<template>
  <div>
    <h1>WebSocket 示例</h1>
    <button @click="sendMessage">发送消息</button>
    <div>
      {{ messages }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from "vue";
import SockJS from "sockjs-client";
import { Stomp } from "@stomp/stompjs";

const messages = ref();
let stompClient: any = null;

//websocket连接
const connect = () => {
  const socket = new SockJS("http://localhost:8080/ws");
  stompClient = Stomp.over(socket);
  stompClient.connect(
    {},
    (frame: string) => {
      console.log("Connected: " + frame);
      stompClient.subscribe("/topic/greetings", (message: { body: string }) => {
        console.log("Received: " + message.body);
        messages.value = message.body;
        //messages.value.push(message.body);
      });
    },
    (error: string) => {
      console.error("Error: " + error);
    }
  );
};

//发送消息
const sendMessage = () => {
  if (stompClient && stompClient.connected) {
    stompClient.send("/app/hello", {}, "hello, world");
  } else {
    console.error("No STOMP connection available");
  }
};

onMounted(() => {
  connect();
});

onBeforeUnmount(() => {
  if (stompClient) {
    stompClient.disconnect();
  }
});
</script>

<style scoped>
/* 添加你的样式 */
</style>

springboot

引入依赖

        <!-- Spring Boot WebSocket依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

websocket配置

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;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@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")
                .setAllowedOrigins("http://localhost:9090") // 允许的来源列表
                .withSockJS(); // 注册 WebSocket 端点,并启用 SockJS 备份传输方式
    }
}

controller


    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public String greeting(String message) {
        System.out.println(message);
        return "你好";
    }

测试

点击按钮

 另一个连接这个广播主题的页面也会接受到信息

后端控制台

 

 ===============================注意====================================

这里说明一下,假如vue文件里的onMounted将连接和发送两个函数写在一起,即:

onMounted(() => {
  connect();

  sendMessage();
});

 你会发现sendMessage()里并没有发送到后端,后端你也没有返回消息。

原因:

异步性:WebSocket 连接是异步的。这意味着 connect 函数会立即返回,而实际的连接过程会在之后发生。因此,如果您在 connect 函数返回后立即调用 sendMessagestompClient 可能还没有被成功初始化,因为连接可能还没有建立。