仿牛客网项目---消息队列的实现

本篇文章讲一讲我们的项目中用到的消息队列。

 

1.阻塞队列

2.kafka

我的项目为什么要用消息队列?

如果采用消息队列,那么评论、点赞、关注三类不同的事,可以定义三类不同的主题(评论、点赞、关注),发生相应的事件可以将其包装成一条消息放入对应的队列里。那么当前的线程可以继续处理下一条消息,不用处理后续的业务(后续由消费者线程处理)。面向事件驱动编程。

3.发布系统通知

下面讲讲怎么发布系统通知。

在entity包下创建event类:

public class Event {

    private String topic;  //表示事件的主题的字符串
    private int userId;     //表示与事件相关的用户的ID
    private int entityType;   //表示与事件相关的实体类型
    private int entityId;      //表示与事件相关的实体的ID
    private int entityUserId;    //表示与实体相关的用户的ID
    private Map<String, Object> data = new HashMap<>();   //一个Map对象,用于存储与事件相关的附加数据

    //省略了很多get()方法和set()方法
}

通过使用这个Event类,我就可以创建一个事件对象,并设置事件的主题、用户ID、实体类型、实体ID、实体用户ID以及其他相关的附加数据。

接着在在community的event目录下创建EventProducer、EventCnsumer类。

@Component
public class EventProducer {

    @Autowired
    private KafkaTemplate kafkaTemplate;

    // 处理事件
    public void fireEvent(Event event) {
        // 将事件发布到指定的主题
        kafkaTemplate.send(event.getTopic(), JSONObject.toJSONString(event));
    }

}

通过调用fireEvent方法,我们就可以将一个事件对象发送到Kafka消息队列中的指定主题。这样,消费者可以从该主题订阅事件,并对事件进行相应的处理逻辑。

@Component
public class EventConsumer implements CommunityConstant {
 
    private static final Logger logger = LoggerFactory.getLogger(EventConsumer.class);
 
    @Autowired
    private MessageService messageService;
 
    @KafkaListener(topics = {TOPIC_COMMENT, TOPIC_LIKE, TOPIC_FOLLOW})
    public void handleCommentMessage(ConsumerRecord record) {
        if (record == null || record.value() == null) {
            logger.error("消息的内容为空!");
            return;
        }
 
        Event event = JSONObject.parseObject(record.value().toString(), Event.class);
        if (event == null) {
            logger.error("消息格式错误!");
            return;
        }
 
        // 发送站内通知
        Message message = new Message();
        message.setFromId(SYSTEM_USER_ID);
        message.setToId(event.getEntityUserId());
        message.setConversationId(event.getTopic());
        message.setCreateTime(new Date());
 
        Map<String, Object> content = new HashMap<>();
        content.put("userId", event.getUserId());
        content.put("entityType", event.getEntityType());
        content.put("entityId", event.getEntityId());
 
        if (!event.getData().isEmpty()) {
            for (Map.Entry<String, Object> entry : event.getData().entrySet()) {
                content.put(entry.getKey(), entry.getValue());
            }
        }
 
        message.setContent(JSONObject.toJSONString(content));
        messageService.addMessage(message);
    }
}

handleCommentMessage方法中,首先检查接收到的消息是否为空,然后将消息内容解析为Event对象。如果解析失败,会记录错误并返回。

接下来,根据接收到的事件信息,构建一个站内通知的Message对象。设置发送者ID为系统用户ID,接收者ID为事件关联的实体用户ID,会话ID为事件主题,创建时间为当前时间。

然后,构建一个存储事件相关信息的content映射。

最后,将content转换为JSON字符串,并将其设置为站内通知的内容。

说了一堆乱七八糟的,反正就是这段代码提供了一个事件消费者类,用于订阅和处理从Kafka消息队列中接收到的指定事件主题的消息。它可以根据事件的类型执行相应的处理操作,例如发送站内通知等。

在评论、点赞、关注视图层增加方法。

CommentController。LikeController。Followcontroller。

4.显示系统通知

消息未读使用拦截器实现,因为每个请求都需要记录次数。

@Component
public class MessageInterceptor implements HandlerInterceptor {
 
    @Autowired
    private HostHolder hostHolder;
 
    @Autowired
    private MessageService messageService;
 
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        User user = hostHolder.getUser();
        if (user != null && modelAndView != null) {
            int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null);
            int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null);
            modelAndView.addObject("allUnreadCount", letterUnreadCount + noticeUnreadCount);
        }
    }
}

上面的这段代码提供了一个消息拦截器类,用于在请求处理完成后,对返回的ModelAndView对象进行拦截和处理,以实现消息的统计和展示功能。

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

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

相关文章

Makedown语法

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

考研C语言复习初阶(5)

目录 一.表达式求值 1.1隐式类型转换 1.2 算术转换 12.3 操作符的属性 二. 指针是什么&#xff1f; 三 指针和指针类型 3.1 指针-整数 3.2 指针的解引用 3.3 野指针 四.指针运算 4.1 指针-整数 4.2 指针-指针 4.3 指针的关系运算 5. 指针和数组 6. 二级指针 …

【学习笔记】VMware vSphere 6.7虚拟化入门

VMware vSphere 6.7虚拟化入门课程介绍 课程内容 1、VMware vSphere 6.7虚拟化入门课程介绍 2、ESXi6.7控制台设置 3、使用vSpkere Host client管理虚拟机 4、VMware EsXi基础操作 5、VMware Esxi存储管理 6、管理ESXi主机网络与虚拟机网络 7、安装配置vCenter Server Applia…

哈希表|1.两数之和

力扣题目链接 /*** Note: The returned array must be malloced, assume caller calls free().*/// leetcode 支持 ut_hash 函式庫typedef struct {int key;int value;UT_hash_handle hh; // make this structure hashable} map;map* hashMap NULL;void hashMapAdd(int key, i…

【JAVA类】利用接口的多继承实现———图书管理系统【附源码】

引言 在我们学习了一些java的基础语法之后&#xff0c;需要把这些知识点可以串起来&#xff0c;这里使用一个简单的小项目可以很好的帮助我们牢记这些知识点&#xff0c;今天就带大家学习一个有关java的小项目&#xff0c;很多学校也经常把这个项目作为他们的课程设计——经典的…

HTML5+CSS3小实例:按钮边框动效

实例:按钮边框动效 技术栈:HTML+CSS 效果: 源码: 【HTML】 <!DOCTYPE html> <html lang="zh-CN"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.…

git入门到精通

第3章 Git常用命令 3.1 设置用户签名 3.2 初始化本地库 3.3 查看本地 状态 3.3.1 首次查看&#xff08;工作区没有任何文件&#xff09; 3.3.2 新增文件&#xff08;hello.txt&#xff09; 3.3.3 再次查者&#xff08;检測到末追踪的文件&#xff09; 3.4添加暫存区 3…

System Verilog学习笔记(二十)——TCL基础

TCL简介 TCL&#xff08;Tool Command Language&#xff09;是一种解释执行的脚本语言。它提供了通用的编程能力&#xff1a;支持变量、过程和控制结构&#xff1b;同时TCL还拥有功能强大的固有的核心命令集 由于TCL的解释器是用C/C语言的过程库实现的&#xff0c;因此可以把T…

Unity笔记:C#基础(1)

杂项 虚函数 CSDN - C虚函数详解 cnblog - C#中的虚函数virtual 常量池与new 在C#中&#xff0c;string是不可变的&#xff0c;这意味着对string对象的操作通常会返回一个新的string对象&#xff0c;而不会修改原始的string对象。因此&#xff0c;几乎所有涉及更改string内…

现在可以在Mac桌面上快速打开C知道进行AI提问

看&#xff0c;我的Mac桌面有个C知道组件&#xff0c;点击即可快速打开C知道页面进行提问使用&#xff0c;再也不需要先打开浏览器&#xff0c;再输入csdn.net访问网站&#xff0c;然后点击页面上的C知道入口。 这是如何实现的呢&#xff1f; 首先&#xff0c;我们来做一些准…

微信聊天助手

最近我在负责公司的招聘工作时&#xff0c;真是深感繁琐与困扰。每当新添加求职者的微信&#xff0c;为了了解他们的基本情况以及求职意向&#xff0c;不得不反复地提出一系列固定的问题。比如询问他们的教育背景、工作经验、擅长技能、期望职位等等&#xff0c;这些必不可少却…

东京工业大学最新!一种具有多周期特征描述的精确ORB提取器

作者&#xff1a;小柠檬 | 来源&#xff1a;3DCV 在公众号「3DCV」后台&#xff0c;回复「原论文」可获取论文pdf 添加微信&#xff1a;dddvision&#xff0c;备注&#xff1a;3D高斯&#xff0c;拉你入群。文末附行业细分群 详细内容请关注3DCV 3D视觉精品课程&#xff1a;…

【每日一题】2834. 找出美丽数组的最小和-2024.3.8

题目&#xff1a; 2834. 找出美丽数组的最小和 给你两个正整数&#xff1a;n 和 target 。 如果数组 nums 满足下述条件&#xff0c;则称其为 美丽数组 。 nums.length n.nums 由两两互不相同的正整数组成。在范围 [0, n-1] 内&#xff0c;不存在 两个 不同 下标 i 和 j &…

P5266 【深基17.例6】学籍管理题解

题目 您要设计一个学籍管理系统&#xff0c;最开始学籍数据是空的&#xff0c;然后该系统能够支持下面的操作&#xff08;不超过条&#xff09;&#xff1a; 插入与修改&#xff0c;格式1 NAME SCORE&#xff1a;在系统中插入姓名为NAME(由字母和数字组成不超过20个字符的字符…

博客系统(SSM)

前端页面http://t.csdnimg.cn/zwKyG以上是之前写过的博客前端页面的内容&#xff0c;下面是通过SSM实现的后端内容。 目录 一.准备工作 1.1数据准备 1.2修改配置版本文件 1.3配置数据库 二.项目公共模块 2.1实体类 2.2操作数据库部分 三.功能开发 3.1博客列表 获取博…

【2024】使用Vuetifi搭建vue3+Ts项目,并使用tailwind.css

目录 使用Vuetifi搭建项目使用tailwind.css 只要跟着官方文档来就不会出错。 使用Vuetifi搭建项目 npm create vuetifyyarn create vuetifypnpm create vuetifybun create vuetify在终端运行一个就行&#xff0c;之后就可以选配置了。 使用tailwind.css 先运行&#xff1a; …

最大的单入口空闲区域

最大的单入口空闲区域 问题描述输入输出代码实现 问题描述 找到最大的单入口空闲区域。 空闲区域是由连通的’O’组成的区域&#xff0c;位于边界的’O’可以是入口&#xff0c; 单入口空闲区域即有且只有一个位于边界的’O’作为入口的由连通的’O’组成的区域。 如果两个元素…

救命!RPA隐藏的高效办公秘密居然被我发现了

在这个快节奏的社会&#xff0c;办公效率的重要性日益凸显。如何提升工作效率&#xff0c;成为了许多公司和个人思考的问题。RPA&#xff0c;即机器人流程自动化技术&#xff0c;正以其独特的优势&#xff0c;成为提升办公效率的重要工具。 RPA的核心是模拟人类在计算机系统中进…

哈希表|434.四数相加II

力扣题目链接 struct hashTable {int key;int val;UT_hash_handle hh; };int fourSumCount(int* A, int ASize, int* B, int BSize, int* C, int CSize, int* D, int DSize) {struct hashTable* hashtable NULL;for (int i 0; i < ASize; i) {for (int j 0; j < BSiz…

jdk1.8安装步骤及环境配置

jdk1.8安装步骤及环境配置 1.1&#xff1a;安装步骤 在Oracle官网下载jdk1.8&#xff0c;下载链接 &#xff0c;如果之前没有注册过还需要注册。下载好之后会得到如下的图标&#xff0c; 双击下载好的exe文件&#xff0c;选择更改安装路径&#xff1a;D:\Java\jdk1.8&#xf…