【问题标题】:Using Pub/Sub and Long Polling使用 Pub/Sub 和长轮询
【发布时间】:2014-10-11 19:46:18
【问题描述】:

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

另外,我想使用长轮询将新消息从服务器传输到客户端。我不使用网络套接字的原因是因为我在组织的代理中可能会遇到一些麻烦。

据我在网上阅读,这听起来像是问题的标准解决方案。

您能否建议处理长轮询请求之间发送的消息的最佳解决方案是什么?用户如何不会错过消息?

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

【问题讨论】:

  • 如果这仍然感兴趣,下面的 Go 库正好处理这种情况,从实际的 Web 服务器中抽象出 pubsub+longpoll,因此你包装它的协议无关紧要,http、ws、 amqp 或其他任何东西:github.com/ventu-io/go-longpoll

标签: architecture chat scalability


【解决方案1】:

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

GET /rooms/1034/chats

由于有数据,您的服务器会立即响应。

回复:

{
  "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!" }
  ]
}

现在客户端可以显示三个聊天,然后向服务器询问更多。这就是长轮询开始的地方 - 由于服务器没有更多的聊天,API 调用会阻塞,直到有新的聊天到达。

GET /rooms/1034/chats?after=2

.. 服务器阻塞,直到有人添加新聊天..

回复:

{
  "chats": [
    { "sequence": 4, "by": "frodo", "message": "I'm here too!" }
  ]
}

关键是客户端本身维护了一个“游标”,因此您不需要在服务器上维护任何每个客户端的缓存等。

当然还有更多。服务器不能永远阻塞,所以在一段时间后(可能是 60 秒)它应该会回复,但会出现超时消息。

在 Spring 中,通过 DeferredResult 支持服务器处理此问题,而不会占用每个客户端的整个线程。

【讨论】:

    猜你喜欢
    • 2013-07-28
    • 2013-07-13
    • 1970-01-01
    • 2022-01-13
    • 2021-11-09
    • 2017-12-07
    • 1970-01-01
    • 2011-10-17
    • 2019-08-11
    相关资源
    最近更新 更多