前端:vue3+ts
后端:springboot
npm安装依赖
cnpm install sockjs-client stompjs
前端代码
<template><div><el-input v-model="message" type="text" placeholder="发送" /><el-button-group><el-button type="primary" @click="sendMessage">发送</el-button><el-button type="primary" @click="">断开连接</el-button></el-button-group><div v-for="(chatMessage, username) in chatMessages" :key="username"><strong>{{ username }}:</strong> {{ chatMessage }}</div></div>
</template><script lang="ts">
import SockJS from 'sockjs-client';
import Stomp from 'stompjs';
import {onMounted, onUnmounted, ref} from "vue";export default {name: 'TestChat',setup() {const message = ref('');const chatMessages = ref({} as Record<string, string>);let stompClient: Stomp.Client;const connectWebSocket = () => {const socket = new SockJS('http://localhost:8600/chat'); // SockJS端点stompClient = Stomp.over(socket);stompClient.connect({// 在这里添加simpUsername头信息'simpusername': "username1"}, (frame) => {console.log('已连接: ' + frame);// ... 订阅消息、发送消息等逻辑stompClient.subscribe('/topic/private/' +"username1", (chatMessage) => {const messageData = JSON.parse(chatMessage.body);chatMessages.value[messageData.username] = messageData.message;});});// stompClient.onerror = (error:any) => {// console.error('112233WebSocket Error:', error);// };//断开连接try{stompClient.disconnect(()=>{console.error('WebSocket连接已断开');})}catch(e){console.error('WebSocket连接已断开');}};const sendMessage = () => {if (stompClient && message.value ) {// const targetUser = prompt('Enter the username of the recipient:');const targetUser = 'touserId' ;const chatMessage = {username: "username",message: message.value,};stompClient.send("/app/private/" + targetUser, {'simpusername': "username1"}, JSON.stringify(chatMessage));message.value = ''; // 清空输入框}};onMounted(() => {connectWebSocket();});onUnmounted(() => {if (stompClient) {stompClient.disconnect();}});return {message,chatMessages,sendMessage,};},
};
</script>
sockjs-client会报错:
Uncaught ReferenceError: global is not defined
解决方法:
在 index.html 中添加脚本:
<script type="text/javascript" >if (window.global === undefined) {window.global = window;}</script>
后端
关键的pom依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency>
我全部的pom依赖:
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-commons</artifactId><version>2.2.1.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.7.11</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.7.11</version></dependency><!-- 一、导入依赖--><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.0.1</version></dependency><!-- mysql依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.15</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--nacos客户端依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.4.1</version></dependency><!--openfeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency></dependencies>
代码:
配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.*;/*** 配置 WebSocket 端点*/
@EnableWebSocketMessageBroker
@Configuration
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {/*** <dependency>* <groupId>org.springframework.boot</groupId>* <artifactId>spring-boot-starter-websocket</artifactId>* </dependency>* @param config*/@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {config.enableSimpleBroker("/topic");config.setApplicationDestinationPrefixes("/app");}@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/chat").setAllowedOrigins("*").withSockJS();}
}
controller:
import org.springframework.messaging.handler.annotation.*;
import org.springframework.stereotype.Controller;@Controller
public class ChatController {@MessageMapping("/private/{toUsername}")@SendTo("/topic/private/{toUsername}")public String sendToUser(String message, @Header("simpusername") String username,@DestinationVariable String toUsername) throws Exception {// Save message to the databaseSystem.out.println("username:"+username+" toUsername:"+toUsername+" message:"+message);return "{from: " + username + ", to : " + toUsername + " , message : " + message + "}";}
}
启动类:
@SpringBootApplication
public class TestApplication {public static void main(String[] args) {SpringApplication.run(TestApplication.class, args);}
}