Sprint Cloud Stream整合RocketMq和websocket实现消息发布订阅

1.引入RocketMQ依赖:首先,在pom.xml文件中添加RocketMQ的依赖:

<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.0</version> <!-- 版本号根据实际情况调整 -->
</dependency>

2.配置RocketMQ连接信息:在application.propertiesapplication.yml中配置RocketMQ的连接信息,包括Name Server地址等:

spring:application:name: ${sn.publish}cloud:stream:rocketmq:binder:name-server: ${rocket-mq.name-server}bindings:output:producer:group: testSocketsync: truebindings:output:destination: test-topiccontent-type: application/json

3.消息发布组件

@Component
public class MqSourceComponent {@ResourceSource source;public void publishNotify(SampleNotifyDTO notify) {source.output().send(MessageBuilder.withPayload(notify).build());}
}

4.消息发布控制器

@RestController
@Api(tags = "rocketmq")
public class MqController {@ResourceMqSourceComponent mq;@ApiOperation(value = "测试发布消息")@PostMapping("test-publish")public JsonVO<String> testSend(SampleNotifyDTO notify) {mq.publishNotify(notify);return JsonVO.success("消息已发送");}
}

项目结构:

接下来是websocket模块的搭建

1. 依赖添加

<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.0</version> <!-- 版本号根据实际情况调整 -->
</dependency>

2.application.yml配置文件

server:port: ${sp.ws}
spring:application:name: ${sn.ws}cloud:stream:rocketmq:binder:name-server: ${rocket-mq.name-server}bindings:input:destination: test-topiccontent-type: application/jsongroup: testSocket

3.将应用程序绑定到消息代理

@EnableBinding(Sink.class): 这是Spring Cloud Stream的注解,它用于将应用程序绑定到消息代理(如Kafka、RabbitMQ等)。Sink.class是Spring Cloud Stream提供的预定义输入通道,允许你接收消息。通过这个注解,你的应用程序可以监听消息通道,并定义消息处理逻辑。

@SpringBootApplication
@EnableDiscoveryClient
@EnableBinding(Sink.class)
public class WsApplication {public static void main(String[] args) {SpringApplication.run(WsApplication.class, args);}}

4.消息订阅组件

监听消息通道中的消息,一旦有消息到达,就会触发listenNotify方法,该方法负责处理消息并通过chat服务发送响应。

@Component
@Slf4j
public class MqListenComponent {@ResourceChatService chat;@StreamListener(Sink.INPUT)public void listenNotify(SampleNotifyDTO notify) {log.info(notify.toString());chat.sendMessage(notify.getClientId(), notify);}
}

5.消息通知服务

package com.zeroone.star.ws.service;import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import org.springframework.stereotype.Component;import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;@Component
@ServerEndpoint("/chat")
public class ChatService {/*** 连接会话池*/private static ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();@OnOpenpublic void onOpen(Session session) throws IOException {// 判断客户端对象是否存在if (SESSION_POOL.containsKey(session.getQueryString())) {CloseReason closeReason = new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "ID冲突,连接拒绝");session.getUserProperties().put("reason", closeReason);session.close();return;}// 将客户端对象存储到会话池SESSION_POOL.put(session.getQueryString(), session);System.out.println("客户端(" + session.getQueryString() + "):开启了连接");}@OnMessagepublic String onMessage(String msg, Session session) throws IOException {// 解析消息 ==> ID::消息内容String[] msgArr = msg.split("::", 2);// 处理群发消息,ID==all表示群发if ("all".equalsIgnoreCase(msgArr[0])) {for (Session one : SESSION_POOL.values()) {// 排除自己if (one == session) {continue;}// 发送消息one.getBasicRemote().sendText(msgArr[1]);}}// 指定发送else {// 获取接收方Session target = SESSION_POOL.get(msgArr[0]);if (target != null) {target.getBasicRemote().sendText(msgArr[1]);}}return session.getQueryString() + ":消息发送成功";}@OnClosepublic void onClose(Session session) {// 连接拒绝关闭会话Object reason = session.getUserProperties().get("reason");if (reason instanceof CloseReason) {CloseReason creason = (CloseReason) reason;if (creason.getCloseCode() == CloseReason.CloseCodes.CANNOT_ACCEPT) {System.out.println("拒绝客户(" + session.getQueryString() + "):关闭连接");return;}}// 从会话池中移除会话SESSION_POOL.remove(session.getQueryString());System.out.println("客户端(" + session.getQueryString() + "):关闭连接");}@OnErrorpublic void onError(Session session, Throwable throwable) {System.out.println("客户端(" + session.getQueryString() + ")错误信息:" + throwable.getMessage());}@SneakyThrowspublic void sendMessage(String id, Object message) {// 群发if ("all".equalsIgnoreCase(id)) {for (Session one : SESSION_POOL.values()) {// 发送消息one.getBasicRemote().sendText(JSONUtil.toJsonStr(message));}}// 指定发送else {// 获取接收方Session target = SESSION_POOL.get(id);if (target != null) {target.getBasicRemote().sendText(JSONUtil.toJsonStr(message));}}}
}

项目结构:

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始开发图床工具:使用 Gitee 和 Electron 实现上传、管理和分享

说在前面 平时写文章或写代码的时候&#xff0c;都少不了需要将本地图片转成在线图片链接&#xff0c;大家都是使用什么工具进行转换的呢&#xff1f;相信很多人都有自己的图床工具&#xff0c;今天来给大家介绍一下&#xff0c;怎么基于Gitee和Electron来开发一个便捷的图床工…

CSP-J 2023 第二轮认证入门级(含答案)

一。题目 二。答案 T1 ⼩苹果&#xff08;apple&#xff09; 每⼀轮拿掉的苹果数量为 。模拟拿苹果的过程&#xff0c;每⼀轮中令 &#xff0c;当 时最后⼀个苹果会被拿掉。 时间复杂度为对数。 #include <iostream> using namespace std; int n; int ans1, ans2; boo…

Kafka KRaft模式探索

1.概述 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。其核心组件包含Producer、Broker、Consumer&#xff0c;以及依赖的Zookeeper集群。其中Zookeeper集群是Kafka用来负责集群元数据的管理、控制器的选举等。 2.内容…

san.js源码解读之模版解析(parseTemplate)篇——readIdent函数

一、源码分析 /*** 读取ident* 这里的 ident 指标识符(identifier)&#xff0c;也就是通常意义上的变量名* 这里默认的变量名规则为&#xff1a;由美元符号($)、数字、字母或者下划线(_)构成的字符串** inner* param {Walker} walker 源码读取对象* return {string}*/ functio…

CNCC2023

中国工程院院士&#xff0c;之江实验室主任、阿里云创始人王坚&#xff1a;计算驱动的科学发现和科技创新。 国际计算机学会主席雅尼斯约阿尼迪斯(ACM President Yannis Ioannidis)。 电气和电子工程师协会计算机协会主席妮塔帕特尔(IEEE CS President Nita Patel)。 2022 I…

StripedFly恶意软件框架感染了100万台Windows和Linux主机

导语 近日&#xff0c;一款名为StripedFly的恶意软件框架在网络安全研究人员的监视之外悄然感染了超过100万台Windows和Linux系统。这款跨平台的恶意软件平台在过去的五年中一直未被察觉。在去年&#xff0c;卡巴斯基实验室发现了这个恶意框架的真实本质&#xff0c;并发现其活…

高三高考免费试卷真题押题知识点合集

发表于安徽 温馨提示&#xff1a;有需要的真题试卷可联系本人&#xff0c;百卷内上免费资源。 感觉有用的下方三连&#xff0c;谢谢 ​ 。 免费版卷有6-60卷每卷平均4-30页 高三免费高三地理高三英语高三化学高三物理高三语文高三历史高三政治高三数学高三生物 付费版卷有1…

Java8与JDK1.8与JDK8之间的关系是什么?

1.Java8等价于JDK8 2.JDK8或者JDK1.8是由于自从JDK1.5/JDK5命名方式改变后遗留的历史问题。所以JDK8或者JDK1.8是等价的。 2004年9月30日&#xff0c;J2SE1.5发布。为了表示该版本的重要性&#xff0c;J2SE 1.5更名为Java SE 5.0&#xff0c;从此开始&#xff0c;如下图像jav…

OpenCV官方教程中文版 —— 直方图均衡化

OpenCV官方教程中文版 —— 直方图均衡化 前言一、原理二、 OpenCV 中的直方图均衡化三、 CLAHE 有限对比适应性直方图均衡化 前言 本小节我们要学习直方图均衡化的概念&#xff0c;以及如何使用它来改善图片的对比。 一、原理 想象一下如果一副图像中的大多是像素点的像素值…

实用篇-认识微服务

一、服务架构演变 1. 单体架构 单体架构&#xff1a;将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 单体架构的优点&#xff1a; 架构简单部署成本低 单体架构的缺点&#xff1a; 耦合度高 2. 分布式架构 分布式架构&#xff1a; 根据业务功能对系…

【C语言】字符函数、字符串函数与内存函数

简单不先于复杂&#xff0c;而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…

【软考系统架构设计师】2021年系统架构师综合知识真题及解析

本文主要分享2021年下半年系统架构师综合知识历年真题以及本人在做题时的所思所想。题目序号有点混乱&#xff0c;可忽略 【01】.某计算机系统页面大小为4K&#xff0c;进程P1的页面变换表如下图所示&#xff0c;看P1要访问数据的逻辑地址为十六进制1B1AH,那么该逻辑地址经过变…