Solon 之 STOMP
一、STOMP 简介
如果直接使用 WebSocket 会非常累,就像用 Socket 编写 Web 应用。没有高层级的交互协议,就需要我们定义应用间所发消息的语义,还需要确保连接的两端都能遵循这些语义。
如 HTTP 在 TCP 套接字之上添加了请求-响应模型层一样,STOMP 是在 WebSocket 之上提供了基于帧的线路格式层,用来定义消息的语义。
与 HTTP 请求和响应类似,STOMP 帧由命令、一个或多个头信息以及负载组成。像下面这段,就是发送数据的一个 STOMP 帧:
SEND
transaction:tx-0
destination:/app/hello
content-length:20{"message":"Hello!"}
在这个示例中,STOMP 命令是 send,表明会发送一些内容。紧接着是三个头信息:一个表示消息的的事务机制,一个用来表示消息要发送到哪里的目的地,另外一个则包含了负载的大小。然后,紧接着是一个空行,STOMP 帧的最后是负载内容。
二、服务端实现
1、启用STOMP功能
STOMP 的消息根据前缀的不同分为三种。如下,以 /app 开头的消息都可以路由到带有 @Mapping 注解的方法中;以/topic 开头的消息都会发送到 STOMP 代理中,根据你所选择的 STOMP 代理不同,目的地的可选前缀也会有所限制;以 /user 开头的消息会将消息重路由到某个用户独有的目的地上。
添加依赖
<dependency><groupId>org.noear</groupId><artifactId>solon-net-stomp</artifactId>
</dependency>
添加端点监听,并设定 broker 目的地前缀
@ServerEndpoint("/demo")
public class DemoStompBroker extends StompBroker {public DemoStompBroker() {this.setBrokerDestinationPrefixes("/topic/");}
}
2、处理来自客户端的STOMP消息
服务端处理客户端发来的 STOMP 消息,主要用的是 @Mapping 注解(和 MVC 开发一样),也可以增加 @Message 方式限有定注解。如下:
@Message //如果不加,同时匹配 http 及其它请求
@Mapping("/app/marco")
@To("*:/topic/marco")
public Shout greeting(Shout shout) throws Exception {log.debug("接收到消息:" + shout.getMessage());Shout s = new Shout();s.setMessage("Polo!");return s;
}
2.1 @Mapping 指定目的地是 /app/marco(我们将其约定为应用的目的地前缀)。
2.2 方法接收一个 Shout 参数,因为 Solon 的执行器根据内容类型自动会将 STOMP 消息的负载转换为 Shout 对象。
2.3 尤其注意,这个处理器方法有一个返回值,这个返回值并不是返回给客户端的,而是转发给消息代理的,如果客户端想要这个返回值的话,只能从消息代理订阅。@To 注解重写了消息代理的目的地,如果不指定@To,帧所发往的目的地会与触发处理器方法的目的地相同。
2.4 如果客户端就是想要服务端直接返回消息呢?听起来不就是HTTP做的事情!即使这样,STOMP 仍然为这种一次性的响应提供了支持,用的还是@Mapping 注解,与HTTP不同的是,这种请求-响应模式是异步的…
@Message
@Mapping("/app/getShout")
public Shout getShout(){Shout shout = new Shout();shout.setMessage("Hello STOMP");return shout;
}
3、发送消息到客户端
3.1 在应用的任意地方发送消息
使用 StompEmitter 接口,可以实现自由的向任意目的地发送消息。
@Inject
private StompEmitter stompEmitter;/**
* 通过 http 接口,广播消息
*/
@Http
@Mapping("/broadcastShout")
public void broadcast(Context ctx, Shout shout) {String json = ctx.renderAndReturn(shout); //渲染数据stompEmitter.sendTo("/topic/shouts", json);
}
3.2 更多发送消息的方式
如果消息只想发送给特定的用户呢?或者发给当前用户?或者所有订阅用户?solon-net-stomp 给了两种方式来实现这种功能:
- 一种是 StompEmitter 接口的 sendTo 方法。
- 一种是 基于 @To 注解。
| StompEmitter 接口 | 对应的 @To 注解 | 说明 |
|---|---|---|
@To("target:destination?") | To 注解表达式(stomp 请求时有效) | |
| sendToSession | @To(".:/...") 或@To(".") | 发给当前客户端订阅者 |
| sendToUser | @To("user:/...") 或@To("user") | 发给特定用户订阅者 |
| sendTo | @To("*:/...") 或@To("*") | 发给代理,再转发给所有订阅者 |
4、处理消息异常
在处理消息的时候,有可能会出错并抛出异常。因为STOMP消息异步的特点,发送者可能永远也不会知道出现了错误。可以调整端点监听,添加 StompListener 实现。
@ServerEndpoint("/demo")
public class DemoStompBroker extends StompBroker implements StompListener{public DemoStompBroker(){//可选:添加鉴权监听器(此示例,用本类实现监听)this.addListener(this);this.setBrokerDestinationPrefixes("/topic/");}@Overridepublic void onError(StompSession session, Throwable error) {//可选:如果出错,反馈给客户端(比如用 "/user/app/errors")getEmitter().sendToSession(session,"/user/app/errors",new Message(error.getMessage()));}
}
三、客户端
STOMP 可以使用 stomp.js。接口参考: https://stomp-js.github.io/api-docs/latest/classes/Client.html
1、创建连接并订阅
let stomp = new StompJs.Client({brokerURL: "ws://127.0.0.1:8080/demo?user=user01",onConnect: function (frame) {stomp.subscribe("/topic/marco", function (message) {let obj = JSON.parse(message.body);console.log("订阅的服务端消息:" + obj.message);});stomp.subscribe("/app/getShout", function (message) {let obj = JSON.parse(message.body);console.log("订阅的服务端应胜消息:" + obj.message);});stomp.subscribe("/user/app/errors", function (message) {console.log("订阅的服务端返回的异常消息:" + message.body);});}
});
2、发送消息
stomp.publish({destination: "/app/marco",headers: {"content-type": "text/json"},body: JSON.stringify({"message": "Marco!"})
});
相关文章:
Solon 之 STOMP
一、STOMP 简介 如果直接使用 WebSocket 会非常累,就像用 Socket 编写 Web 应用。没有高层级的交互协议,就需要我们定义应用间所发消息的语义,还需要确保连接的两端都能遵循这些语义。 如 HTTP 在 TCP 套接字之上添加了请求-响应模型层一样…...
在掌控板上搭建http服务器
在掌控板上搭建http服务器 打开Arduino IDE,并且已经添加了ESP32的支持库。以下是创建一个基本HTTP服务器的步骤: 包含必要的库: #include <WiFi.h> #include <WebServer.h>配置WiFi: 替换ssid和password为你的WiFi网…...
HCIA复习实验
实验要求 实验拓扑以及实验分析 第一步先划分网段 先对内网划分 192.168.1.0/24划分 192.168.1.0/26---骨干主线路 192.168.1.64/26---骨干备线路 ---192.168.1.128/25--vlan2 3汇总---便于减少路由表条目---在大型网络方便 192.168.1.128/26---vlan2 192.168.1.192/26---vla…...
生信软件39 - GATK最佳实践流程重构,提高17倍分析速度的LUSH流程
1. LUSH流程简介 基因组测序通常用于分子诊断、分期和预后,而大量测序数据在分析时间方面提出了挑战。 对于从FASTQ到VCF的整个流程,LUSH流程在非GVCF和GVCF模式下都大大降低了运行时间,30 X WGS数据耗时不到2 h,从BAM到VCF约需…...
c#编写的各类应用程序、类库的引用(黑白盒)
001 课程简介,C# 语言简介,开发环境准备 (yuque.com)https://www.yuque.com/yuejiangliu/dotnet/timothy-csharp-001 一个Solution里包含多个Project 一、见识 C# 编写的各类应用程序 二、类库的引用(黑/白盒引用) 1、黑盒引用&a…...
计算机网络考研笔记
...
用感性的方式浅要了解什么是AI 与 大模型
什么是人工智能(AI)? 人工智能(Artificial Intelligence,简称 AI)是指由人制造出来的具有一定智能的系统,能够理解和学习人类的行为,并在某些任务上模仿人类的智能行为。这些任务包…...
Linux文件的查找和打包以及压缩
文件的查找 文件查找的用处,在我们需要文件但却又不知道文件在哪里的时候 文件查找存在着三种类型的查找 1、which或whereis:查找命令的程序文件位置 2、locate:也是一种文件查找,但是基于数据库的查找 3、find:针…...
专题十四_哈希表_算法专题详细解答
目录 哈希表简介 1. 两数之和(easy) 解析: 解法一:暴力: 解法二:哈希O(N) 总结: 2. 判断是否互为字符重排(easy) 解析: 哈希: 总结&…...
C++源码生成·序章
文章目录 C源码生成序章1 概述1.1 前言1.2 Python 易用性简介 2 使用 python 生成 c 源码2.1 运行脚本2.2 结果 3 项目启动3.1 项目概述3.2 环境准备3.3 克隆仓库3.4 查看标签(Tags)3.4 根据标签拉取代码3.5 后续步骤 C源码生成序章 1 概述 1.1 前言 …...
Android中的MVP模式
MVP(Model-View-Presenter)架构在 Android 开发中是一种流行的架构模式,它将业务逻辑和 UI 代码分离,通过 Presenter 来处理用户的操作和界面更新。MVP 提高了代码的可维护性和测试性,特别是 Presenter 中的逻辑可以单…...
kebuadm部署k8s集群
官方文档: Installing kubeadm | Kubernetes 切记要关闭防⽕墙、selinux、禁用交换空间, cpu核⼼数⾄少为2 内存4G kubeadm部署k8s⾼可用集群的官方文档: Creating Highly Available Clusters with kubeadm | Kubernetes 你需要在每台…...
Unity3D学习FPS游戏(2)简单场景、玩家移动控制
前言:上一篇的时候,我们已经导入了官方fps的素材,并且对三维模型有了一定了解。接下来我们要构建一个简单的场景让玩家能够有地方移动,然后写一个简单的玩家移动控制。 简单场景和玩家移动 简单场景玩家移动控制玩家模型视野-摄像…...
网上的 AQS 文章让我很失望
一、AQS 很多人都没有讲明白 🤔 翻看了网上的 AQS(AbstractQueuedSynchronizer)文章,质量参差不齐,大多数都是在关键处跳过、含糊其词,美其名曰 “传播知识” 。 大多数都是进行大段的源码粘贴和注释&…...
滑动窗口子串
文章目录 滑动窗口一、无重复字符的最长子串二、找到字符串中所有字母异位词 子串三、和为 K 的子数组四、滑动窗口最大值五、最小覆盖子串 滑动窗口 一、无重复字符的最长子串 题目链接 (方法一:暴力枚举) (方法二ÿ…...
【windows11 提示“Microsoft Visual C++ Runtime Library Runtime Error】
windows11 提示“Microsoft Visual C++ Runtime Library Runtime Error” 问题描述解决方法郑重声明:本人原创博文,都是实战,均经过实际项目验证出货的 转载请标明出处:攻城狮2015 Platform: windows OS:windows11 问题描述 解决方法 下载VisualCppRedist_AIO_x86_x64.exe 安…...
【leetcode|哈希表、动态规划】最长连续序列、最大子数组和
目录 最长连续序列 解法一:暴力枚举 复杂度 解法二:优化解法一省去二层循环中不必要的遍历 复杂度 最大子数组和 解法一:暴力枚举 复杂度 解法二:贪心 复杂度 解法三:动态规划 复杂度 最长连续序列 输入输…...
【人工智能】掌握深度学习中的时间序列预测:深入解析RNN与LSTM的工作原理与应用
深度学习中的循环神经网络(RNN)和长短时记忆网络(LSTM)在处理时间序列数据方面具有重要作用。它们能够通过记忆前序信息,捕捉序列数据中的长期依赖性,广泛应用于金融市场预测、自然语言处理、语音识别等领域…...
今日开放!24下软考机考「模拟练习平台」操作指南来啦!
2024年下半年软考机考模拟练习平台今日开放,考生可以下载模拟作答系统并登录后进行模拟练习,熟悉答题流程及操作方法。 一、模拟练习时间 2024年下半年软考机考模拟练习平台开放时间为2024年10月23日9:00至11月6日17:00,共15天。 考生可以在…...
合并.md文档
需求:将多个.md文档合并成一个.md文档。 方法一:通过 type 命令 参考内容:多个md文件合并 步骤: 把需要合并的 .md 文档放入到一个文件夹内。修改需要合并的 .md 文档名,可以在文档名前加上 1.2.3 来表明顺序&#x…...
RetinaFace效果展示:高精度人脸检测与关键点定位案例
RetinaFace效果展示:高精度人脸检测与关键点定位案例 1. RetinaFace模型核心能力解析 RetinaFace作为当前最先进的人脸检测算法之一,在精度和效率方面都达到了业界领先水平。这个基于ResNet50构建的模型能够同时完成三项关键任务: 人脸检测…...
别再死记命令了!用EVE-NG模拟器5分钟搞定思科GRE隧道(附OSPF联动配置)
5分钟玩转思科GRE隧道:EVE-NG实战中的高效学习法 第一次在EVE-NG里搭建GRE隧道时,我盯着满屏的命令行发呆——这些配置到底在做什么?为什么tunnel接口要配源和目的地址?OSPF又是怎么和隧道联动的?直到我用Wireshark抓到…...
如何用torchtext快速构建文本分类模型?5分钟上手RoBERTa与T5实战教程
如何用torchtext快速构建文本分类模型?5分钟上手RoBERTa与T5实战教程 【免费下载链接】text Models, data loaders and abstractions for language processing, powered by PyTorch 项目地址: https://gitcode.com/gh_mirrors/te/text 想要在PyTorch生态中快…...
革新性PDF打印解决方案:PDFtoPrinter全场景应用指南
革新性PDF打印解决方案:PDFtoPrinter全场景应用指南 【免费下载链接】PDFtoPrinter .Net Wrapper over PDFtoPrinter util allows to print PDF files. 项目地址: https://gitcode.com/gh_mirrors/pd/PDFtoPrinter 价值定位:重新定义PDF打印体验…...
从巨鲸到万物生长:Claude Code如何颠覆AI开发,带你从对话走向Agent平台搭建!
Claude Code凭借其六大核心能力,将AI开发带入全新阶段。通过CLAUDE.md实现项目记忆增强,Skills固化可复用工作流,Sub-Agent处理专业化任务,MCP连接外部服务,Plug-In打包完整解决方案。本文深入解析这些功能,…...
如何让实验室管理“更简单”?——King’s LIMS以灵活与智能,重构高效运营新范式
在日常实验室管理中,流程繁琐、数据难溯源、报告生成低效、多场景管控混乱等问题,常成为拖慢运营节奏、抬升运维成本的“隐形阻力”。要打破管理困局、实现轻量化高效运维,选对数字化工具是关键。然而,在选择LIMS的过程中…...
GPT-5-Codex CLI实战:如何用UIUIApi中转服务稳定获取API Key(避坑指南)
GPT-5-Codex CLI高效实践:国内开发者API接入全流程解析 最近在技术社区里,关于GPT-5-Codex的讨论热度持续攀升。作为一名长期关注AI编程工具的开发者,我发现很多同行在尝试接入这项服务时遇到了各种技术障碍。本文将分享一套经过实战验证的完…...
文档下载工具:突破平台限制的高效获取策略与零成本解决方案
文档下载工具:突破平台限制的高效获取策略与零成本解决方案 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是…...
League-Toolkit:英雄联盟智能辅助工具的效率提升之道
League-Toolkit:英雄联盟智能辅助工具的效率提升之道 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit League-Toolkit是…...
3步搞定ViGEmBus:Windows虚拟游戏手柄驱动终极指南 [特殊字符]
3步搞定ViGEmBus:Windows虚拟游戏手柄驱动终极指南 🎮 【免费下载链接】ViGEmBus Windows kernel-mode driver emulating well-known USB game controllers. 项目地址: https://gitcode.com/gh_mirrors/vi/ViGEmBus 想要在Windows上体验更丰富的游…...
