Architecture 使用Pub/Sub和长轮询

Architecture 使用Pub/Sub和长轮询,architecture,chat,scalability,Architecture,Chat,Scalability,我想实现一个可伸缩的聊天应用程序。 因此,我想使用pub/sub技术(当有人发送消息时,它会被发送到整个房间)。由于其简单性,我选择了Redis缓存服务器 此外,我希望使用长轮询将新消息从服务器传输到客户端。我不使用web套接字的原因是,我可能会在组织的代理中遇到一些问题 据我在网上读到的,这听起来像是解决这个问题的标准方法 您能告诉我什么是处理长轮询请求之间发送的消息的最佳解决方案吗?用户如何不错过一条消息 听起来我需要为每个客户机保存一个缓存,其中包含他自己的消息。但这样做——我不会利用发布

我想实现一个可伸缩的聊天应用程序。 因此,我想使用pub/sub技术(当有人发送消息时,它会被发送到整个房间)。由于其简单性,我选择了Redis缓存服务器

此外,我希望使用长轮询将新消息从服务器传输到客户端。我不使用web套接字的原因是,我可能会在组织的代理中遇到一些问题

据我在网上读到的,这听起来像是解决这个问题的标准方法

您能告诉我什么是处理长轮询请求之间发送的消息的最佳解决方案吗?用户如何不错过一条消息


听起来我需要为每个客户机保存一个缓存,其中包含他自己的消息。但这样做——我不会利用发布/订阅技术。我可以向会议室中的每个用户发送消息,而不是pub/sub。

使用长轮询方法,客户端可以像这样对服务器进行API调用(在本例中,可以查看1034会议室中的所有聊天,其中已经有3个聊天):

因为有数据要处理,所以服务器会立即响应

答复:

{
  "chats": [
    { "sequence": 0, "by": "fred", "message": "hey guys, anyone in this room?" },
    { "sequence": 1, "by": "fred", "message": "anyone at all?" },
    { "sequence": 2, "by": "bill", "message": "yeah I'm here!" }
  ]
}
{
  "chats": [
    { "sequence": 4, "by": "frodo", "message": "I'm here too!" }
  ]
}
现在,客户端可以显示这三个聊天,然后向服务器询问更多信息。这就是长轮询开始的地方——由于服务器没有更多的聊天,API调用会一直阻塞,直到出现新的聊天

GET /rooms/1034/chats?after=2
。。服务器阻塞,直到有人添加新聊天

答复:

{
  "chats": [
    { "sequence": 0, "by": "fred", "message": "hey guys, anyone in this room?" },
    { "sequence": 1, "by": "fred", "message": "anyone at all?" },
    { "sequence": 2, "by": "bill", "message": "yeah I'm here!" }
  ]
}
{
  "chats": [
    { "sequence": 4, "by": "frodo", "message": "I'm here too!" }
  ]
}
关键的一点是,客户机本身维护一个“游标”来指示它所在的位置,因此您不需要在服务器上维护任何每客户机缓存等

当然还有很多。服务器不能永远阻塞,因此在一段时间(可能是60秒)后,它应该回复,但会显示一条超时消息


在Spring中,服务器可以通过DeferredResult处理此问题,而无需为每个客户端占用整个线程。

如果这仍然是一个有趣的问题,下面的Go库将从实际的web服务器中抽象出pubsub+longpoll来处理此问题,因此,围绕它的协议(http、ws、,amqp或任何其他: