Spring Boot 中的 @SendTo 注解

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 消息转发功能的关键注解,可以让我们轻松地实现消息的发送和接收。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MOOC 测验】第4章 网络层

1‌、下列关于路由算法描述错误的是&#xff08; &#xff09; A. 链路状态算法是一种全局路由算法&#xff0c;每个路由器需要维护全局状态信息B. OSPF 是一种域内路由协议&#xff0c;核心是基于 Dijkstra 最低费用路径算法C. RIP 是一种域内路由算法&#xff0c;核心是基…

docker网络

一、docker网络概述 1、docker网络实现的原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c; 同时Docker网桥是 每个容器的…

基于ENVI的遥感影像的非监督分类

ENVI包括了ISODATA和K-Mean两种非监督分类方法。 ISODATA&#xff08;Iterative Self-Orgnizing Data Analysize Technique&#xff09;是一种重复自组织数据分析技术&#xff0c;计算数据空间中均匀分布的类均值&#xff0c;然后用最小距离技术将剩余像元进行迭代聚合&#x…

Unreal 5 实现使用GPU Instancing批量渲染相同的物体

之前做unity的时候&#xff0c;专门研究了使用GPU进行批量相同的物体渲染&#xff0c;现在转ue以后&#xff0c;发现UE也有相同的功能。接下来讲解一下&#xff0c;在ue里面如何实现通过GPU进行实例化渲染。 创建组件 能够实现GPU实例化渲染&#xff0c;ue提供了两个组件&…

最新导则下生态环评报告编制技术暨报告篇、制图篇、指数篇、综合应用篇教程

详情点击链接&#xff1a;最新导则下生态环评报告编制技术暨报告篇、制图篇、指数篇、综合应用篇 一&#xff0c;生态环评报告编制规范 结合生态环境影响评价最新导则&#xff0c;详述不同类型项目生态环评报告编制要求与规范 二&#xff0c;土地利用图 1、土地利用分类体系…

go系列-读取文件

1 概述 2 整个文件读入内存 直接将数据直接读取入内存&#xff0c;是效率最高的一种方式&#xff0c;但此种方式&#xff0c;仅适用于小文件&#xff0c;对于大文件&#xff0c;则不适合&#xff0c;因为比较浪费内存。 2.1 直接指定文化名读取 在 Go 1.16 开始&#xff0c;i…

HackTheBox - 学院【CPTS】复习4 - Web Attacks

Web Attacks 本模块涵盖三种常见的 Web 漏洞&#xff0c;即 HTTP 动词篡改、IDOR 和 XXE&#xff0c;每个漏洞都可能对公司的系统产生重大影响。我们将介绍如何通过各种方法识别、利用和防止它们中的每一个。 HTTP HEAD/GET/POST/PUT/OPTIONS IDOR寻找 一般能够从前端js找到…

.Net 4726.0 Razor编译时的小差异

前言 几个月前在进行着.Net 472到6.0的升级&#xff0c;复用原有代码&#xff0c;在对Razor进行迁移中&#xff0c;发现原运行正常的代码&#xff0c;却存在报错&#xff0c;深入研究发现是Core下对Razor编译有一些变动。 问题复现 472 创建视图 新建.Net Framework下Mvc&#…

软件测试的自动化工具

在软件开发过程中&#xff0c;测试是必不可少的一个环节。而在测试中&#xff0c;测试人员需要花费大量的时间和精力进行手动测试&#xff0c;这不仅费时费力&#xff0c;而且效率较低。因此&#xff0c;自动化测试工具的出现为测试人员提供了更加便捷高效的测试方法。本文将介…

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

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

Spring Boot 中的 WebSocketSession 是什么,原理,如何使用

Spring Boot 中的 WebSocketSession 是什么&#xff0c;原理&#xff0c;如何使用 介绍 在现代 Web 应用程序中&#xff0c;实时通信是一个非常常见的需求。传统的 HTTP 协议是无法支持实时通信的&#xff0c;因为它是一种无状态协议&#xff0c;每次请求都是独立的&#xff0…

LangChain:LLM应用程序开发(上)——Models、Prompt、Parsers、Memory、Chains

文章目录 一、Models、Prompt、Parsers1.1 环境配置&#xff08;导入openai&#xff09;1.2 辅助函数&#xff08;Chat API : OpenAI&#xff09;1.3 使用OpenAI API进行文本翻译1.4使用LangChain进行文本翻译1.5 使用LangChain解析LLM的JSON输出1.5.1 LangChain输出为string格…

基于Java的万年历(课设)

基于Java的万年历 资源链接&#xff1a;基于Java的万年历&#xff08;课设&#xff09; 文章目录 基于Java的万年历1 绪论2 需求分析3 概要设计3.1 类间组合框架3.2 布局结构示意3.3 对各个类的概述 4运行环境5 开发工具和编辑语言6 详细设计6.1 NiceCaelendar类6.2 NiceFram…

LeetCode 2501 数组中最长的方波 Java

方法一&#xff0c;哈希表枚举 构造哈希集合&#xff0c;记录出现过的数字枚举遍历 import java.util.HashSet; import java.util.Set;class Solution {public int longestSquareStreak(int[] nums) {//构造哈希表集合&#xff0c;记录出现过的数字&#xff0c;转long型&…

如何在Microsoft Excel中迅速冻结首行和末行

如果你正在处理一个大型电子表格&#xff0c;那么冻结某些行或列会很有用&#xff0c;这样当你滚动浏览工作表的其余部分时&#xff0c;它们会留在屏幕上。 当你在 Excel 中滚动浏览大的工作表时&#xff0c;你可能希望保留一些行或列&#xff0c;例如页眉。Excel 允许你通过以…

2023年华中杯数学建模B题小学数学应用题相似性度量及难度评估解题全过程文档及程序

2023年华中杯数学建模 B题 小学数学应用题相似性度量及难度评估 原题再现 某 MOOC 在线教育平台希望能够进行个性化教学&#xff0c;实现用户自主学习。在用户学习时&#xff0c;系统从题库中随机抽取若干道与例题同步的随堂测试题&#xff0c;记录、分析学生的学习和答题信息…

网络安全实战植入后门程序

在 VMware 上建立两个虚拟机&#xff1a;win7 和 kali。 Kali&#xff1a;它是 Linux 发行版的操作系统&#xff0c;它拥有超过 300 个渗透测试工具&#xff0c;就不用自己再去找安装包&#xff0c;去安装到我们自己的电脑上了&#xff0c;毕竟自己从网上找到&#xff0c;也不…

前端Vue自定义轮播图swiper 轮播图dot 轮播图指示indicate

前端Vue自定义轮播图swiper 轮播图dot 轮播图指示indicate&#xff0c;下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13193 效果图如下: ​ 编辑切换为居中 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; ​…

【HTTP 协议1】图文详解 HTTP 请求和应答报文

文章目录 前言一、认识 HTTP 协议1, 什么是 HTTP 协议2, HTTP 协议的报文格式 二、HTTP 请求报文1, 认识方法1.1, GET 和 POST 辨析(重点)1.2, 其他方法 2, 认识 URL3, 认识 Header3.1, Host3.2, Content-Length3.3 Content-Type3.4, User-Agent3.5, Referer3.6, Cookie(重点) …

【C#】并行编程实战:任务并行性(下)

本教程对应学习工程&#xff1a;魔术师Dix / HandsOnParallelProgramming GitCode 本章继续介绍任务并行性&#xff0c;因篇幅所限&#xff0c;本章为下篇。 6、处理任务异常 所有优秀的程序员都擅长高效地处理异常&#xff0c;这也是并行编程最重要的方面之一。任务并…