Spring Boot 中的 @SendTo 注解

news2024/11/18 6:35:51

Spring Boot 中的 @SendTo 注解

在 Spring Boot 中,@SendTo 注解是一个非常有用的注解,它可以用于实现 WebSocket 的消息转发功能。本文将介绍 @SendTo 注解的原理、使用方法和示例代码。

在这里插入图片描述

什么是 @SendTo 注解

@SendTo 注解是 Spring Boot 中用于将消息发送到指定目的地的注解。它可以用于 WebSocket 中的消息转发功能,将客户端发送的消息转发到指定的目的地,让指定的客户端接收到消息。

@SendTo 注解的原理

@SendTo 注解的原理是利用了 WebSocket 中的消息订阅和发布机制。在 WebSocket 中,每个客户端都可以订阅指定的目的地,当有消息发布到该目的地时,所有订阅该目的地的客户端都会收到该消息。

@SendTo 注解可以将消息发送到指定的目的地,让订阅该目的地的客户端接收到消息。在发送消息时,@SendTo 注解会将消息封装成一个 Message 对象,并将其发送到指定的目的地。客户端在订阅该目的地时,就可以接收到该消息。

如何使用 @SendTo 注解

使用 @SendTo 注解非常简单,只需要在方法上添加该注解,并指定需要发送到的目的地即可。下面是一个使用 @SendTo 注解的示例:

@RestController
public class WebSocketController {

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        Thread.sleep(1000); // simulated delay
        return new Greeting("Hello, " + message.getName() + "!");
    }

}

以上代码中,@MessageMapping("/hello") 注解表示该方法用于处理客户端发送的 /hello 消息。@SendTo("/topic/greetings") 注解表示将返回的消息发送到 /topic/greetings 目的地。

客户端在订阅 /topic/greetings 目的地时,就可以接收到该消息了。示例代码如下:

var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
    stompClient.subscribe('/topic/greetings', function(greeting){
        showGreeting(JSON.parse(greeting.body).content);
    });
});

以上代码中,stompClient.subscribe('/topic/greetings', function(greeting){...}) 表示订阅 /topic/greetings 目的地,并在收到消息时触发回调函数,将消息显示在页面上。

示例代码

为了更好地理解 @SendTo 注解的使用方法,下面给出一个完整的示例代码。该示例代码实现了一个简单的聊天室功能,用户可以在聊天室中发送消息,其他用户可以收到消息。

首先,我们需要创建一个 WebSocket 配置类,用于配置 WebSocket 的相关参数。代码如下:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat").withSockJS();
    }

}

以上代码中,configureMessageBroker 方法用于配置消息代理,registerStompEndpoints 方法用于注册 WebSocket 端点。enableSimpleBroker("/topic") 表示启用简单的消息代理,并将消息发送到 /topic 目的地。setApplicationDestinationPrefixes("/app") 表示设置应用程序前缀为 /appaddEndpoint("/chat").withSockJS() 表示注册一个 WebSocket 端点,并启用 SockJS 支持。

接下来,我们需要创建一个 WebSocket 控制器类,用于处理客户端发送的消息。代码如下:

@RestController
public class WebSocketController {

    private final SimpMessagingTemplate messagingTemplate;

    public WebSocketController(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @MessageMapping("/chat.sendMessage")
    @SendTo("/topic/public")
    public ChatMessage sendMessage(@Payload ChatMessage chatMessage) {
        return chatMessage;
    }

    @MessageMapping("/chat.addUser")
    @SendTo("/topic/public")
    public ChatMessage addUser(@Payload ChatMessage chatMessage,
                               SimpMessageHeaderAccessor headerAccessor) {
        headerAccessor.getSessionAttributes().put("username", chatMessage.getSender());
        return chatMessage;
    }

}

以上代码中,@MessageMapping("/chat.sendMessage") 注解表示该方法用于处理客户端发送的 /chat.sendMessage 消息。@SendTo("/topic/public") 注解表示将返回的消息发送到 /topic/public 目的地。sendMessage 方法用于发送消息。

@MessageMapping("/chat.addUser") 注解表示该方法用于处理客户端发送的 /chat.addUser 消息。addUser 方法用于添加用户。

最后,我们需要创建一个前端页面,用于显示聊天室界面,并处理用户输入的消息。代码如下:

<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Chat Example</title>
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script type="text/javascript">
        var stompClient = null;

        function connect() {
            var socket = new SockJS('/chat');
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function (frame) {
                console.log('Connected: ' + frame);
                stompClient.subscribe('/topic/public', function (chatMessage) {
                    showMessage(JSON.parse(chatMessage.body));
                });
            });
        }

        function disconnect() {
            if (stompClient !== null) {
                stompClient.disconnect();
            }
            console.log("Disconnected");
        }

        function sendMessage() {
            var sender = $("#sender").val();
            var content = $("#content").val();
            stompClient.send("/app/chat.sendMessage", {}, JSON.stringify({
                sender: sender,
                content: content
            }));
        }

        function addUser() {
            var sender = $("#sender").val();
            stompClient.send("/app/chat.addUser", {}, JSON.stringify({
                sender: sender,
                content: ' has joined the chat'
            }));
        }

        function showMessage(message) {
            $("#chat").append("<tr><td>" + message.sender + ": " + message.content + "</td></tr>");
        }

        $(function () {
            $("form").on('submit', function (e) {
                e.preventDefault();
            });
            connect();
            $("#send").click(function () {
                sendMessage();
                $("#content").val("");
            });
            $("#join").click(function () {
                addUser();
                $("#sender").prop("readonly", true);
                $("#join").prop("disabled", true);
                $("#send").prop("disabled", false);
                $("#content").prop("disabled", false);
            });
        });
    </script>
</head>
<body>
<div>
    <form>
        <label for="sender">Username:</label>
        <input type="text" id="sender" name="sender"/>
        <button type="button" id="join">Join</button>
        <br/>
        <label for="content">Message:</label>
        <input type="text" id="content" name="content"/>
        <button type="button" id="send" disabled="disabled">Send</button>
    </form>
</div>
<div>
    <table id="chat"></table>
</div>
</body>
</html>

以上代码中,connect 方法用于建立 WebSocket 连接。disconnect 方法用于断开 WebSocket 连接。sendMessage 方法用于发送消息。addUser 方法用于添加用户。showMessage 方法用于显示消息。

总结

通过本文的介绍,我们了解了 Spring Boot 中的 @SendTo 注解的原理和使用方法。@SendTo 注解是实现 WebSocket 消息转发功能的关键注解,可以让我们轻松地实现消息的发送和接收。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/705465.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

个人和企业如何有效保护IP地址?

随着互联网的快速发展&#xff0c;个人和企业对于保护IP地址的重要性越来越清晰。为了帮助读者更好地了解如何有效保护IP地址&#xff0c;以下将介绍几种方法&#xff0c;并提供一些相关的数据和专家意见。 使用防火墙是保护IP地址的一个重要手段。防火墙可以监控和过滤网络流量…

react native 使用Native Module、Intent、广播接收器 实现两个app之间的相互通信

一、react native版本环境: “react”: “18.1.0”, “react-native”: “0.70.6”, “node”: "14.18.2 二、发送端步骤: 在A app中注册一个Native Module模块,使用Intent 连接B app,sendBroadcast 发送广播传递数据。 (1)首先在 /android/app/src/main/java/com/j…

ASP.NET Core MVC从入门到精通[PDF版]

随着技术的发展&#xff0c;ASP.NET Core MVC也推出了好长时间&#xff0c;经过不断的版本更新迭代&#xff0c;已经越来越完善&#xff0c;本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容&#xff0c;适用于初学者&#xff0c;在校毕业生&#xff0c…

three.js点材质(PointsMaterial)常用属性设置

一、前景回顾 上一章节简单介绍了下怎么使用点材质和点对象创建物体点对象和点材质介绍 点材质和点对象基本运用示例代码&#xff1a; import * as THREE from "three"; // 导入轨道控制器 import { OrbitControls } from "three/examples/jsm/controls/Orbit…

A核与M核异构通信过程解析

现在越来越多的产品具有M core和A core的异构架构&#xff0c;既能达到M核的实时要求&#xff0c;又能满足A核的生态和算力。比如NXP的i.MX8系列、瑞萨的RZ/G2L系列以及TI的AM62x系列等等。虽然这些处理器的品牌及性能有所不同&#xff0c;但多核通信原理基本一致&#xff0c;都…

Linux操作系统配置代理服务器

PS:本文只是针对Linux操作系统对于代理服务器的配置操作&#xff0c;不涉及广告 1.代理的概念 代理服务器英文全称是Proxy Server&#xff0c;其功能就是代理网络用户去取得网络信息。形象的说&#xff1a;它是网络信息的中转站。在一般情况下&#xff0c;我们使用网络浏览器直…

华为智能高校出口安全解决方案(1)

华为智能高校出口安全解决方案&#xff08;1&#xff09; 视频链接方案背景需求分析高校园区网概述高校园区网全景高校出口场景介绍高校出口整体需求分析业务安全需求攻击防御需求运维审计需求 方案规划华为智能高校出口安全解决方案架构华为智能高校出口安全解决方案功能划分业…

(二)Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方,实现圆点的“彩色拖尾”效果以及“选中方框”效果

系列文章目录 通过Qt实现手势识别控制软件操作相关系列技术方案 &#xff08;一&#xff09;Qt 将某控件、图案绘制在最前面的方法&#xff0c;通过QGraphicsScene模块实现 &#xff08;二&#xff09;Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方&#xff0c;实现圆…

强化学习从基础到进阶-案例与实践[5.1]:Policy Gradient-Cart pole游戏展示

强化学习从基础到进阶-案例与实践[5.1]&#xff1a;Policy Gradient-Cart pole游戏展示 强化学习&#xff08;Reinforcement learning&#xff0c;简称RL&#xff09;是机器学习中的一个领域&#xff0c;区别与监督学习和无监督学习&#xff0c;强调如何基于环境而行动&#x…

关于u(x,t)=f(x)*g(t)形式证明的思考

突然想起来&#xff0c;二维高斯函数是可以拆分成两个一维高斯函数相乘的&#xff1a; 原来在学概率论的时候&#xff0c;证明过&#xff0c;这只能说高斯函数可以&#xff0c;这是一个思路。 一维波动函数应该也是这个套路。 那么还有没有其他函数可以如此&#xff0c;有如此…

javascript和css实现瀑布流排列

Grid 布局 实现瀑布流 html <div class"gridDiv"><divv-for"(item,index) in 20":style"{grid-row: auto / span ${heightArray[index]}}"><div class"gridItemConten"><div class"gridText">{{ite…

VS2022编译运行VS2015的项目

最近新装了VisualStudio2022&#xff0c;有一些VS2015老的项目需要运行&#xff0c;但不想再安装VS2015&#xff0c;就想能否直接在VS2022编译运行&#xff0c;研究一下发现可行&#xff0c;记录一下。 1. 直接升级VS2015项目到2022使用windows sdk 10.0 发现老代码里的一些语…

#10044 「一本通 2.2 例 2」Power Strings(KMP)(内附封面)

题目描述 原题来自&#xff1a;POJ 2406 给定若干个长度 \le 10^6 的字符串&#xff0c;询问每个字符串最多是由多少个相同的子字符串重复连接而成的。如&#xff1a;ababab 则最多有 3 个 ab 连接而成。 输入格式 输入若干行&#xff0c;每行有一个字符串。特别的&#xf…

第一章:R-CNN网络详解(丰富特征层次用于准确的目标检测和语义分割技术报告(v5))

(目标检测篇&#xff09;系列文章目录 第一章:R-CNN网络详解 第二章:Fast R-CNN网络详解 第三章:Faster R-CNN网络详解 第四章:YOLO v1网络详解 第五章:YOLO v2网络详解 第六章:YOLO v3网络详解 文章目录 系列文章目录技术干货集锦前言一、摘要二、正文分析 1.引入库2.读入…

迅为RK3568/RK3588开发板视频教程 | RKNPU2 从入门到实践一套搞定!

迅为电子嵌入式视频教程更新了&#xff01;——「AI深度学习推理加速器--RKNPU2 从入门到实践」&#xff08;基于RK3588和RK3568&#xff09; 课程内容分为三个阶段&#xff1a;认识RKNPU、RKNPU开发学习以及项目实战。 首先&#xff0c;我们将从认识RKNPU阶段开始&#xff0…

Redis实战——短信登录(一)

项目搭建 前期准备 导入SQL CREATE TABLE tb_user (id bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 主键,phone varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 手机号码,password varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4…

【Redis】Redis主从复制哨兵模式集群

文章目录 一、Redis 持久化1. 主从复制2. 哨兵模式3. 集群 二、 Redis 主从复制1. 概述2. 主从复制的作用3. 主从复制流程4. 搭建 Redis 主从复制4.1 环境准备4.2 安装 Redis4.3 修改 Master 节点配置文件4.4 修改Slave节点配置文件&#xff08;Slave1和Slave2配置相同&#xf…

关于Docker中 docker build 时no such file or directory报错

ERROR: failed to solve: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount545066663/Dockerfile: no such file or directory 主要原因是命令行没有在文件夹下执行docker build&#xff0c;cd到指定文件夹下执行即可

windows-x86使用qemu打开x86和arm虚拟机

1、下载qemu软件 下载固件&#xff08;UEFI固件镜像文件&#xff0c;BIOS的替代方案&#xff09;&#xff09; 2、配置qemu环境变量 使用cmd执行qemu命令&#xff0c;配置好环境变量比较方便 3、准备镜像 准备好一个x86的镜像或者arm的镜像&#xff0c;格式可以为qcow2 4、打…

STM32 时钟 寄存器 异常和中断

时钟: 51单片机中有时钟和时钟树的概念&#xff0c;外设只有GPIO、定时器、和一个串口&#xff0c;使用的都是11.0592MHZ的频率&#xff0c;除了定时器外&#xff0c;其他外设只要上电就可以使用。 stm32不同外设对应的时钟频率不同&#xff0c;故有时钟树的概念 PLL&#xf…