任务: 任务是编写一个带有在线聊天、通知和其他通知的服务。它应该通过 websockets 工作。
工作逻辑:用户创建一个连接,向服务器发送一个特定的请求,表示现在他需要通过这个web socket发送所有的通知。旧通知是通过 api 接收的。
服务器上的实现:我认为加载旧消息的时间很清楚,只是向数据库发出请求。新消息的情况如何:在创建这样的消息后,它最终会出现在某个消息中,store其中启动了一个无限循环,对 this 的数据进行无休止的检查store。当无限循环中的函数看到那里出现了新消息/通知时,它会将其发送给接收它的用户并将其从store. 通过水平扩展,这将store留给单独服务器上的单独应用程序。
问题:某些消息或通知可能会丢失/重复。假设我们连接到通知服务并将它们发送给我们。但在接受此类通知之前,我们必须通过向数据库发出请求来下载旧的。以下是选项:
- 首先,我们从 api 加载通知,然后我们连接到通知服务。它不起作用 - 当来自 api 的响应飞向我们时,可能会出现一条新消息,我们不会以任何方式知道它,因为我们尚未连接到通知服务。
- 好的,首先我们连接到通知服务,然后我们向 api 发出请求。当 api 处理我们的请求时,我们收到了 3 个通知。接下来是来自 api 的响应。以及如何解析这些通知?当然,我可以查看id,删除相同的id,最后插入其他的。但它看起来像某种自行车。我想要一个更简洁的解决方案
- 为通知和下载旧通知创建 1 个处理程序?没问题!但现在同样的问题,只在服务器端,因为当我从数据库中获取数据时,
insert可能会变成一条新消息。它没有采取。当然,自行车出现在我的脑海中,有各种各样的选择来同步整个事情,但它是如此复杂和不可靠,以至于我立即将它们扔掉 - 我不会在 1 个线程中处理所有这些,因为它无法扩展并且依赖于 1 个服务器的 1 个核心的性能。
- 在数据库中创建一个已发送的列,每次通过在通知服务中敲击base来检查发送?不是!
如果您需要可靠的交付,那么没有非常简单的解决方案。有一些或多或少可以接受。选择还取决于一些附加条件。
您描述的选项 2 可能是最简单的。特别是如果您的客户端存储状态、已读取的确切内容、用户看到的通知等。毕竟,你还是得以某种方式维护这个状态,并与服务器端来的东西同步,至少会有第一次调用api的逻辑,会考虑到已经加载的东西,以免接收到重复(或在接收后明确忽略它们)。在这种情况下,消除通知中收到的重复数据并不困难。当然,有必要等待对 api 的请求完成,然后再显示此时已到达的通知。
如果您对单个用户中的所有消息和通知有一个全局顺序,选项 1 可能会很好用。那些。如果在收到 api 的响应后,在订阅通知时,您传递了通过 api 接收的最新消息的标识符(获取序列号或时间戳所需的标识符)。然后通知服务,在将当前可用的消息发送给客户端之前,会先从数据库中获取所有丢失的消息,首先将它们发送给客户端,然后才会从
store.可以以序列化为单个用户创建消息的(小)成本为用户的消息进行全局排序(即,一个用户不能将两条消息并行插入数据库),但不需要在一个线程中完成所有处理。