# 发送系统通知
封装事件 当事件被触发时,发送相关的数据
set方法返回值设置为事件本身 方便实现连续调用event.set().set
public class Event {
private String topic; //事件的主题
private int userId; //发送人
private int entityType; //事件对象的类型 比如帖子的类型
private int entityId; //帖子的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;
}
}
编写事件的生产者
把event对象转为JSON字符串
@Component
public class EventProducer {
@Autowired
private KafkaTemplate kafkaTemplate;
//处理事件
public void fireEvent(Event event)
{
//将事件发布到指定的主题
kafkaTemplate.send(event.getTopic(), JSONObject.toJSONString(event));
}
}
编写事件的消费者
一个方法处理多个主题
把JSON字符串转化为对象
会话id存储为系统通知主题 内容为JSON字符串
把content转为JSON字符串存放到content字段里
@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 handleMessage(ConsumerRecord record){
if(record==null||record.value()==null){
logger.error("消息内容为空!");
return;
}
//把JSON字符串转化为事件对象
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if(event==null){
logger.error("消息格式错误!");
return;
}
//发送站内通知
//创建新的Message
Message message=new Message();
//获取消息的发送人
message.setFromId(SYSTEM_USER_ID);
//设置消息的接受人
message.setToId(event.getEntityId());
//设置消息的主题
message.setConversationId(event.getTopic());
message.setCreateTime(new Date());
//使用map创建content 放入其他内容
Map<String,Object> content=new HashMap<>();
//放入触发消息的用户id
content.put("userId",event.getUserId());
content.put("entityType",event.getEntityType());
content.put("entityId",event.getEntityId());
//如果事件还有其他信息,遍历事件的Map Data,放入到content
if(!event.getData().isEmpty()){
for(Map.Entry<String,Object> entry:event.getData().entrySet()){
content.put(entry.getKey(),entry.getValue());
}
}
//把content转为JSON字符串存放到content字段里
message.setContent(JSONObject.toJSONString(content));
//把信息存入到数据库
messageService.addMessage(message);
}
}
触发事件
当生产者生产内容(即发送信息的时候)消费者会自动处理消息,因此只需要增加生产者触发事件即可
修改commentController likeController followController
查找评论的对象的作者需要先判断作者是什么类型
//触发评论事件
Event event=new Event()
.setTopic(TOPIC_COMMENT)
.setUserId(hostHolder.getUser().getId())
.setEntityType(comment.getEntityType())
.setEntityId(comment.getEntityId())
.setData("postId",discussPostId);
//查找评论的对象的作者需要先判断作者是什么类型
if(comment.getEntityType()==ENTITY_TYPE_POST){
DiscussPost discussPost = discussPostService.selectPostById(comment.getEntityId());
event.setEntityUserId(discussPost.getUserId());
}else if(comment.getEntityType()==ENTITY_TYPE_POST){
Comment target=commentService.findCommentById(comment.getEntityId());
event.setEntityUserId(target.getUserId());
}
eventProducer.fireEvent(event);
点赞的时候触发事件
增加一个postid
//触发点赞事件
if(likeStatus==1) {
Event event = new Event()
.setTopic(TOPIC_LIKE)
.setUserId(hostHolder.getUser().getId())
.setEntityType(entityType)
.setEntityId(entityId)
.setEntityUserId(entityUserId)
.setData("postId", postId);
eventProducer.fireEvent(event);
}
//触发关注事件
Event event = new Event()
.setTopic(TOPIC_FOLLOW)
.setUserId(hostHolder.getUser().getId())
.setEntityType(entityType)
.setEntityId(entityId)
.setEntityUserId(entityId);
eventProducer.fireEvent(event);