From 42ae5ef1afaf255d072f2c1482bf01fa7f5277ab Mon Sep 17 00:00:00 2001 From: Azure <983547216@qq.com> Date: Mon, 22 Jun 2026 13:41:36 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20SseEventPublisher?= =?UTF-8?q?=20Redis=20Pub/Sub=20=E4=BA=8B=E4=BB=B6=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/event/SseEventPublisher.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/java/com/webgame/webgamebackend/common/event/SseEventPublisher.java diff --git a/src/main/java/com/webgame/webgamebackend/common/event/SseEventPublisher.java b/src/main/java/com/webgame/webgamebackend/common/event/SseEventPublisher.java new file mode 100644 index 0000000..ca1c27f --- /dev/null +++ b/src/main/java/com/webgame/webgamebackend/common/event/SseEventPublisher.java @@ -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 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); + } +}