SSE/Redis-如何恢复SSE脱机时发送的消息



在一个网站上,我有一个非常简单的实时聊天设置,它使用SSE/Redis和pub/sub结构。

基本设置(不详细说明(是:

  1. 使用EventSource的客户端

打开SSE连接并订阅SSE后台进程发送的实时事件。向API端点发送消息

connect(hash, eventListener) {
const url = `${url}?client=$hash=${hash}`;
sseSource = new EventSource(url);
sseSource.onopen = function(e) {
reconnectFrequencySeconds = 1;
}
sseSource.onerror = err => {
this.closeSSEStream();
this.reconnectSSEStream(hash, eventListener);
};
sseSource.addEventListener('messages', event => {
const messages = JSON.parse(event.data);
eventListener(messages);
});
},
  1. API终点

将消息存储在数据库中,并将其推送到Redis通道。

  1. Redis数据库

用于保存和服务消息。

  1. 服务器端SSE守护进程

将客户端订阅到Redis DB中的通道,并使用SSE流将消息转发给订阅服务器。

const subscriber = redis.createClient();
subscriber.select(config.redisDatabase);
subscriber.on('message', function (channel, message) {
log(connectionId, 'Redis: new msg on channel: ' + channel, message);
let event = {
event: 'messages',
data: message
};
currentClient.connection.write(event);
});

整件事做得很好,然而,它离完美只有一步之遥。在部署期间,我们重新启动我们的工作程序(包括SSE守护进程(,当它离线时,用户不会收到实时更新。它重新连接得很好,但在停机期间发送的消息会丢失(因为守护进程仅在重新连接时开始侦听消息(。

我唯一的解决方法是使用一种过度设计的解决方案,在重新连接时,使用单独的API端点收集"丢失"消息并将其显示给用户。

在订阅频道之前,是否有现成的方式来接收存储在Redis中的消息?例如,"弹出"未处理的消息或类似的东西?

当您重新连接时,发送请求以检查您是否是新的消息以及上次消息的时间如果你是新的消息,在结果消息中发送它,以避免新的请求

最新更新