前端端口: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
函数返回后立即调用 sendMessage
,stompClient
可能还没有被成功初始化,因为连接可能还没有建立。