首页 > 解决方案 > 无法使用 SSE 向连接的客户端发送消息

问题描述

我正在尝试使用 SSE 向连接的客户端发送消息。

我已将 SseEmitter 对象保存在 redis 中,以便我可以获取相同的对象并将消息发送给客户端。

但是,消息没有发送到客户端。

当我用一个简单的列表进行测试时,它工作正常。但是,当我有多个客户端时,我需要存储各个客户端的连接信息并发送消息。但是,没有发送消息。

我有一个带有 2 个端点的控制器类, /subscribe/{userId] 用于订阅 SSE 消息,另一个 dispatchEvent 用于将消息从服​​务器推送到客户端。

在我的订阅方法处理程序中,我有以下内容,

@CrossOrigin
@RequestMapping(value="subscribe/{userId}", consumes=MediaType.ALL_VALUE)
public SSEInfo subscribe(@PathVariable("userId") String userId) {
    SSEInfo sseEmitter=new SSEInfo(Long.MAX_VALUE);

    try {
        sseEmitter.send(SseEmitter.event().name("INIT"));
        sseRedisService.save(userId,sseEmitter);
    }catch(IOException e) {
        e.printStackTrace();
    }
    
    sseEmitter.onCompletion( () -> sseRedisService.deleteById(userId));
    sseRedisService.save(userId,sseEmitter);
    return sseEmitter;   
}

在我的 dispatchEvent 处理程序中,我有如下,

@PostMapping(value="dispatchEvent")
public void dispatchEventsToAllClients(@RequestParam String event,@RequestParam String userId) {
        try {
            SSEInfo sseEmitter=(SSEInfo) sseRedisService.findById(userId);      
            sseEmitter.send(SseEmitter.event().name("event").data(event));
        } catch (IOException e) {
            e.printStackTrace();
            sseRedisService.deleteById(userId);
        }
}

在里面,我的服务类SSERedisService的sseRedisService对象,我正在使用 Spring 数据 redis ,

redisTemplate.opsForValue().set(userId,object); to save in redis cache.

对于获取,我使用 ,

redisTemplate.opsForValue().get(userId);

但是,当我调用调度事件时,消息没有发送到客户端。

我通过创建一个扩展 SseEmitter 并实现 Serializable的自定义类SSEInfo来包装 SseEmitter。

我使用以下 CURL 请求,

 curl http://localhost:8085/subscribe/user001
 curl -d "event=teeuser&userId=user001" -X POST http://localhost:8085/dispatchEvent

用于相应地订阅和调度事件。

有人可以帮我解决这个问题。我不确定我们是否可以将 sseEmitter 对象保存到 redis 并再次获取它们以发送回客户端。

完整的源代码也可以在 github repo 中找到,如下所示,

https://github.com/sri420/SSE-Redis

有人可以帮助解决这个问题。

标签: spring-bootredisserver-sent-eventsspring-cache

解决方案


推荐阅读