feat: 添加 SseEventPublisher Redis Pub/Sub 事件发布器

This commit is contained in:
2026-06-22 13:41:36 +08:00
parent 0f240361bb
commit 42ae5ef1af

View File

@@ -0,0 +1,57 @@
package com.webgame.webgamebackend.common.event;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
/**
* SSE 事件发布器
*
* 统一入口,将业务事件序列化后发送到 Redis Pub/Sub 频道,
* 由所有实例的 RedisSseListener 接收并推送到各自连接的客户端。
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class SseEventPublisher {
/** Redis Pub/Sub 频道名 */
public static final String CHANNEL = "sse:events";
private final RedisTemplate<String, String> redisTemplate;
/**
* 发布广播事件(推送给所有在线用户)
*
* @param type 事件类型
* @param data 事件数据对象(将被序列化为 JSON
*/
public void broadcast(SseEventType type, Object data) {
SseEvent event = SseEvent.broadcast(type, JSON.toJSONString(data));
publish(event);
}
/**
* 发布定向事件(只推送给指定用户)
*
* @param userId 目标用户 accountId
* @param type 事件类型
* @param data 事件数据对象(将被序列化为 JSON
*/
public void sendTo(String userId, SseEventType type, Object data) {
SseEvent event = SseEvent.targeted(type, userId, JSON.toJSONString(data));
publish(event);
}
/**
* 将事件序列化为 JSON 并发布到 Redis Pub/Sub 频道
*/
private void publish(SseEvent event) {
String json = JSON.toJSONString(event);
log.debug("[SSE] 发布事件到 Redis, channel={}, eventType={}, targetId={}",
CHANNEL, event.type(), event.targetId());
redisTemplate.convertAndSend(CHANNEL, json);
}
}