• websocket使用案例(前后端springboot+vue)



    前言

    参考资料:spring官网
    案例代码地址:https://spring.io/guides/gs/messaging-stomp-websocket/
    官方文档地址:https://docs.spring.io/spring-framework/reference/web/websocket/stomp/message-flow.html

    使用websocket进行简单的通信,功能大致为广播推送全体消息,根据不同用户推送特定消息

    我这次使用后端springboot+前端vue实现websocket功能


    一、什么时候使用websocket

    示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
    官方文档说的很清楚了,协作、游戏、金融方面都会用到实时数据,其他对要求不高的可以用轮询代替。
    我这次遇到的需要就是多用户协作。

    二、大致需求

    用户A新建一个模板,并分享给其他用户B、C使用,当用户B、C查询自己有哪些可用模板时,用户A对模板作了修改,此时用户B、C应该能感知到,不然使用时就会出问题。

    三、简单代码实现

    3.1 后端代码实现

    后端maven依赖:

    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-websocket</artifactId>
    		</dependency>
    
    • 1
    • 2
    • 3
    • 4

    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;
    
    /**
     * @Author: Ron
     * @Create: 2023-09-27 17:44
     */
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    
        @Override
        public void configureMessageBroker(MessageBrokerRegistry config) {
            config.enableSimpleBroker("/topic","/user");
            config.setApplicationDestinationPrefixes("/app");
        }
    
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/webSocket")
                    .setAllowedOrigins("*");
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    消息处理模块

    import org.jeecg.common.api.vo.Result;
    import org.jeecg.modules.system.entity.SysTicket;
    import org.jeecg.modules.system.mapper.SysTicketMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.simp.SimpMessagingTemplate;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @Author: Ron
     * @Create: 2023-09-27 17:48
     */
    @CrossOrigin
    @RestController
    public class WebsocketController {
    
        @Autowired
        private SimpMessagingTemplate messagingTemplate;
    
        @MessageMapping("/hello")
        public void greeting() {
            messagingTemplate.convertAndSendToUser("ron.yu", "/queue/private", "convertAndSendToUser:Hello World!");
            messagingTemplate.convertAndSend("/topic/greetings", "convertAndSend:Hello, Ron!");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    配置文件

    server:
      port: 8888
      servlet:
        context-path: /cq
    
    • 1
    • 2
    • 3
    • 4

    3.2 前端代码

    vue

    <template>
      <div>
        <h1>WebSocket Example</h1>
        <button @click="connectWebSocket">Connect</button>
        <button @click="disconnectWebSocket">Disconnect</button>
        <input v-model="message" placeholder="Enter a message" />
        <button @click="sendMessage">Send Message</button>
        <ul>
          <li v-for="(greeting, index) in greetings" :key="index">{{ greeting }}</li>
        </ul>
      </div>
    </template>
    
    <script>
    import SockJS from "sockjs-client";
    import Stomp from "stompjs";
    
    export default {
      data() {
        return {
          stompClient: null,
          message: "",
          greetings: [],
          username:""
        };
      },
      methods: {
        connectWebSocket() {
          const socket = new WebSocket("ws://localhost:8888/cq/webSocket"); // 替换成您的WebSocket服务器地址
          this.stompClient = Stomp.over(socket);
    
          this.stompClient.connect({}, frame => {
            console.log("WebSocket连接成功", frame);
            this.stompClient.subscribe("/topic/greetings", greeting => {
              // this.greetings.push(greeting.body);
              console.log("/topic/greetings");
            });
            this.stompClient.subscribe(`/user/${this.message}/queue/private`, message => {
              // 处理私人消息
              // console.log("Received private message:", JSON.parse(message.body));
              console.log("Received private message:");
            });
          });
        },
        disconnectWebSocket() {
          if (this.stompClient) {
            this.stompClient.disconnect(() => {
              console.log("WebSocket断开连接");
            });
          }
        },
        sendMessage() {
          if (this.message) {
            this.stompClient.send(
              "/app/hello",
              {},
              JSON.stringify({ name: this.message })
            );
            // this.message = "";
          }
        }
      }
    };
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    3.3 页面效果展示

    在这里插入图片描述

    四、代码理解

    websocket后端核心模块:
    在这里插入图片描述
    ①:@EnableWebSocketMessageBroker,是一个标志,它告诉 Spring 该类用于配置和启用 WebSocket 服务,然后你需要在该类中定义实际的 WebSocket 端点和处理逻辑。这个注解使得构建 WebSocket 服务更加方便。通过合理配置消息代理,你可以实现消息的分发、广播和点对点通信等功能。
    ②:configureMessageBroker,用于配置消息代理,它是 WebSocketMessageBrokerConfigurer 接口中的一个方法。消息代理是 WebSocket 服务中的核心组件之一,它负责将消息从发送方传递到接收方,充当了消息的中转站。
    ③:config.enableSimpleBroker(“/topic”,“/user”),启用消息代理,意味着可以使用 “/topic” 和 “/user” 作为消息的目的地,消息将由代理传送到订阅这些目的地的客户端。
    ④:config.setApplicationDestinationPrefixes(“/app”),设置应用程序目的地前缀,设置了应用程序目的地的前缀为 “/app”。这意味着客户端可以将消息发送到以 “/app” 开头的目的地,然后消息代理将这些消息路由到相应的消息处理器进行处理。
    ⑤:registerStompEndpoints,用来定义和配置 WebSocket 端点的重要方法,它允许你指定端点的名称、允许的跨域源,以及其他相关配置。
    ⑥:registry.addEndpoint(“/webSocket”),注册了一个名为 “/webSocket” 的 WebSocket 端点。这意味着客户端可以通过 WebSocket 连接到 “/webSocket” 这个端点来进行实时通信。
    ⑦:.setAllowedOrigins("")*,跨域设置,设置了允许来自任何源的跨域 WebSocket 连接。

    在这里插入图片描述
    ⑧:@MessageMapping(“/hello”),是 Spring Framework 中用于处理 WebSocket 消息映射的注解。它的作用是将客户端发送的消息映射到指定的处理方法,以便在接收到特定消息时执行相应的逻辑。
    ⑨:private SimpMessagingTemplate messagingTemplate;,是 Spring Framework 中的一个类,它用于发送消息到 WebSocket 和基于消息的 STOMP 端点,以实现实时通信。
    ⑩:***点对点通信-convertAndSendToUser ***,convertAndSendToUser 方法允许你向指定的用户发送消息,这是一种点对点通信的方式。你可以指定用户名和目标路径,以便将消息发送到特定用户的特定目标。如图,向名为 “ron.yu” 的用户发送了一条消息,目标路径为 “/queue/private”,这是一种点对点通信。
    ***广播通信-convertAndSend ***,convertAndSend 方法允许你向指定的主题广播消息,这是一种一对多通信的方式。多个订阅了相同主题的客户端都将收到该消息。使用 convertAndSend 方法向主题 “/topic/greetings” 广播了一条消息,这是一种广播通信。

    五、什么是websocket的端点?

    WebSocket 端点(WebSocket Endpoint)是 WebSocket 通信的入口点或终端。它是客户端和服务器之间建立 WebSocket 连接的目标位置,充当了通信的起点和终点。WebSocket 端点定义了 WebSocket 通信的具体位置和协议细节。
    WebSocket 端点通常具有一个唯一的名称或路径,客户端可以使用这个名称或路径来建立与端点的连接。例如,一个 WebSocket 端点的路径可以是 “/chat”,客户端可以通过 WebSocket 连接到 “ws://example.com/chat” 来与该端点通信。

    总结

    这些代码只是简单实现了websocket的不同用户消息推送,并没有做权限检验复杂的功能。
    刚写websocket,还是去官网找文档效率更高。

  • 相关阅读:
    Git基本操作
    优化导入大批量数据的Excel(上万行的导入)SpringBoot + Apache POI
    升降 ubuntu 内核的好工具 mainline
    Kruskal 重构树
    SpringBoot程序的打包与运行
    Supervised Machine Learning Regression and Classification(吴恩达机器学习课程笔记)
    程序猿成长之路番外篇-如何理解牛顿迭代法及如何使用牛顿迭代法求数的平方根
    如果让我设计一套,TPS百万级API网关!
    vue 实现前台用户登录
    [计算机毕业设计]机器学习的数据驱动股票价格预测
  • 原文地址:https://blog.csdn.net/qq_35080796/article/details/133384084