实现功能
• 触发事件
- 评论后,发布通知
- 点赞后,发布通知
- 关注后,发布通知
• 处理事件
- 封装事件对象
- 开发事件的生产者
- 开发事件的消费
Event
package com.light.community.entity;
import java.util.HashMap;
import java.util.Map;
/**
* @author light
* @Description
* @create 2023-05-18 16:36
*/
public class Event {
private String topic; //事件类型(话题
private int userId;// 事件的触发者
private int entityType; //实体类型:帖子、评论
private int entityId; //实例id:帖子id、评论id
private int entityUserId; //实体作者:帖子作者、评论作者
//封装其他信息
private Map<String,Object> data=new HashMap<>();
public String getTopic() {
return topic;
}
public Event setTopic(String topic) {
this.topic = topic;
return this;
}
public int getUserId() {
return userId;
}
public Event setUserId(int userId) {
this.userId = userId;
return this;
}
public int getEntityType() {
return entityType;
}
public Event setEntityType(int entityType) {
this.entityType = entityType;
return this;
}
public int getEntityId() {
return entityId;
}
public Event setEntityId(int entityId) {
this.entityId = entityId;
return this;
}
public int getEntityUserId() {
return entityUserId;
}
public Event setEntityUserId(int entityUserId) {
this.entityUserId = entityUserId;
return this;
}
public Map<String, Object> getData() {
return data;
}
public Event setData(String key,Object value) {
this.data.put(key,value);
return this;
}
}
EventProducer
package com.light.community.event;
import com.alibaba.fastjson2.JSONObject;
import com.light.community.entity.Event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Component;
/**
* @author light
* @Description 事件生产者
* @create 2023-05-18 19:57
*/
@Component
public class EventProducer {
@Autowired
private KafkaTemplate kafkaTemplate;
//处理事件
public void fireEvent(Event event){
//将事件发送出去:将事件对象转化成json字符串发送
kafkaTemplate.send(event.getTopic(), JSONObject.toJSONString(event));
}
}
EventConsumer
package com.light.community.event;
import com.alibaba.fastjson2.JSONObject;
import com.light.community.entity.Event;
import com.light.community.entity.Message;
import com.light.community.service.MessageService;
import com.light.community.util.CommunityConstant;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author light
* @Description 事件消费者
* @create 2023-05-18 19:58
*/
@Component
public class EventConsumer implements CommunityConstant {
//记录日志
public static final Logger logger= LoggerFactory.getLogger(EventConsumer.class);
@Autowired
private MessageService messageService;
//消费者消费事件
//最后将事件转化为消息插入到message中
@KafkaListener(topics = {TOPIC_COMMENT,TOPIC_FOLLOW,TOPIC_LIKE})//监听的主题
public void handleMessage(ConsumerRecord record){
//先进行判断record是否为空:未发事件或者发送的事件为空
if(record==null|| record.value()==null){
logger.error("发送的消息为空!");
return;
}
//事件不为空:将事件转换为Event对象
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()); //发送时间
//发送内容:要将内容拼装成发送的消息:xxx用户评论(点赞、关注)了你(的xxx
Map<String,Object> content=new HashMap<>();
content.put("userId",event.getUserId());//事件触发的人
content.put("entityId",event.getEntityId()); //事件id
content.put("entityType",event.getEntityType()); //事件类型
//如果事件还有额外的信息
if(!event.getData().isEmpty()){
for(Map.Entry<String,Object> entry:event.getData().entrySet()){
content.put(entry.getKey(),entry.getValue());
}
}
//将消息内容转化为json字符串
message.setContent(JSONObject.toJSONString(content));
//将message对象存入message表中
messageService.addMessage(message);
}
}
FollowController
//关注
@RequestMapping(value = "/follow",method = RequestMethod.POST)
@ResponseBody //异步请求,局部刷新
public String follow(int entityType,int entityId){
User user = hostHolder.getUser();
followService.follow(user.getId(), entityType,entityId);
//触发关注事件
Event event=new Event()
.setTopic(TOPIC_FOLLOW)
.setUserId(user.getId())
.setEntityId(entityId)
.setEntityType(entityType)
.setEntityUserId(entityId);
eventProducer.fireEvent(event);
return CommunityUtil.getJsonString(0,"已关注!");
}
CommentController
@RequestMapping(value = "/add/{discussPostId}",method = RequestMethod.POST)
public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment){
comment.setStatus(0);
comment.setCreateTime(new Date());
comment.setUserId(hostHolder.getUser().getId());
commentService.addComment(comment);
//发送评论后发送通知通知对方
Event event=new Event()
.setTopic(TOPIC_COMMENT)
.setUserId(hostHolder.getUser().getId())
.setEntityType(comment.getEntityType())
.setEntityId(comment.getEntityId())
.setData("postId",discussPostId); //最终发送的消息还有点击查看,要链接到帖子详情页面,需要知道帖子id
//帖子的作者:评论的是帖子帖子--》帖子表; 评论的是评论---》评论表
if(comment.getEntityType()==ENTITY_TYPE_POST){
DiscussPost target = discussPostService.findDiscussPostById(comment.getEntityId());
event.setEntityUserId(target.getUserId());
} else if (comment.getEntityType()==ENTITY_TYPE_COMMENT) {
Comment target = commentService.findCommentById(comment.getEntityId());
event.setEntityUserId(target.getUserId());
}
//生产者发送实现
eventProducer.fireEvent(event);
return "redirect:/discuss/detail/" + discussPostId;
}
LikeController
@RequestMapping(value = "/like",method = RequestMethod.POST)
@ResponseBody
public String like(int entityType,int entityId,int entityUserId,int postId){
User user = hostHolder.getUser();
//点赞
likeService.like(user.getId(),entityType,entityId, entityUserId);
//获取点赞数量
long likeCount = likeService.findEntityLikeCount(entityType, entityId);
//获取点赞状态
int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);
//返回的结果
Map<String,Object> map=new HashMap<>();
map.put("likeCount",likeCount);
map.put("likeStatus",likeStatus);
//触发点赞事件
if(likeStatus==1){
Event event=new Event()
.setTopic(TOPIC_LIKE)
.setUserId(hostHolder.getUser().getId())
.setEntityId(entityId)
.setEntityType(entityType)
.setEntityUserId(entityUserId)
.setData("postId",postId);
eventProducer.fireEvent(event);
}
return CommunityUtil.getJsonString(0,null,map);
}