来自后端的实时用户通知,具有 PubNub、可扩展性和超过 9000 个聊天室
Real-time user notifications from backend with PubNub, scalability, and over 9000 chat rooms
我正在开发一个非常有趣的 Web 应用程序项目,该项目可能会变得相当大,我有机会使用这个名为 PubNub
的方便的东西作为应用程序的主要实时引擎。
所以它是一个具有 Node.js
后端的 Web 应用程序,涉及用户之间潜在的大量聊天室以及当数据库中的某些数据更新时后端向用户发送的实时通知。
通常,使用Sockets.io
进行开发,我只会为每个用户订阅其唯一DB id 的频道,以及代表不同聊天室的频道。
这样我就可以在后端处理聊天室和身份验证,在数据库中存储一些个人通知后,我可以轻松地将它们推送到以用户 ID 命名的频道,所以如果用户在线 - 他会得到它,如果不在线 - 很好,他将在下次登录时看到它,通知已经在数据库中。从理论上讲,在 redis pub/sub.
的帮助下,这个怪物应该可以很好地水平扩展
在这种情况下,让我担心 PubNub 的是可伸缩性。由于我显然不了解 PubNub 后端的黑暗角落发生了什么,我想确保该应用程序的构建方式能够准备好处理一些晦涩难懂的大量并发用户。
我的问题是,使用 PubNub
构建此类系统的最佳方法是什么?
- 我是否正确假设需要向特定用户推送通知、订阅该用户的 pubnub、推送注释和取消订阅会更好。就好像我要保持所有在线用户渠道开放一样——那么在我的服务器上使用 PubNub 而不是 websockets 是没有意义的,因为服务器无论如何都会承受所有这些打开的在线用户渠道的负载,并且应该进行扩展以保持巨大的规模它们的数量。
- 用户授权呢?在不涉及我的后端的情况下,我如何确定发布某些消息的用户将无法伪造他的个性并且与他在应用程序内部进行身份验证时完全相同?
- 通常(通过 PubNub)处理每个用户的大量聊天的最佳做法是什么?比如在应用生命周期中,每个用户可能会积累一些垃圾聊天室,其中有一些用户,虽然很长时间没有人接触过,用户懒得手动离开?
感谢您耐心阅读这面文字墙!
2021 年 12 月 5 日更新
如果您正在实施聊天应用程序,请参阅 PubNub Chat use-case documentation for full details. It has new features and UI components that are built upon the PubNub Platform。
2020 年 5 月 15 日更新
我们有 some new docs 可以更清楚地解释以下内容。
以及可应用于以下许多 questions/answers 的新功能:
- Message Actions
- Message Counts
- Batch History (multi-channel message fetch)
- Objects (Users, Channels and Memberships Metadata)
注意: 我在下面的答案中加入了上面的一些 links。
首先,让我们解决这个问题...
Thing that worries me about PubNub, in this case, is scalability. As I
obviously have no insight on what is going on in PubNub backend's dark
corners, I want to make sure that the app is built in a way that it will
be prepared to handle some obscure enormously huge amount of
simultaneous users.
还有这个...
then there is no point in PubNub instead of WebSockets on my server,
as the server will be anyway under the load of all of those opened online-user
channels and should be scaled just to maintain the huge quantity of them
这有点落后,因为您会使用像 PubNub 这样的服务来确保您的应用程序可以扩展以处理数百万用户。 PubNub 拥有数以千计的客户,可扩展到数百万用户和数百亿条消息。不知道 PubNub 是如何做到这一点的,您可以自由地实施应用程序的业务逻辑。
但我想我明白你在说什么。您的印象是您的服务器必须参与每个用户的每个聊天室交互,但这只是部分正确。大多数情况下,您的服务器将用于身份验证、一些订阅维护(可选),并可能根据需要(取决于您的要求)向一个、多个或所有最终用户发送消息。
这里有一些尝试来回答你的问题,尽管它们有点到处都是,所以我会尽力回答我认为你在问的问题。
问题 1
这个问题似乎是针对维持大量的频道订阅和它的可扩展性。
一般来说,每个最终用户都会初始化 PubNub 并订阅他们需要收听的频道,并发布到他们需要发送消息的频道。通常,他们发布的频道(我假设是您的聊天室)与他们订阅的频道相同,但它们是不同类型的用例。您可以一次订阅数千个频道(每个客户最多 20K)。如果您使用 WebSockets 做到这一点,您将如何将其扩展到数百万用户?您将实施和操作(以扩展)类似于 PubNub 的东西(不容易且不便宜)。
现在,如果用户订阅了一堆聊天室频道,但其中一些或许多频道已过时(用户有一段时间没有查看或 posted),您可以在上面添加一些代码您的服务器(或客户端)监控用户的 activity 并从那些陈旧的频道中取消订阅。这可以使用 channels groups。每个最终用户都有自己的频道组,其中包含他们正在收听的所有频道。以及客户端代码或服务器代码以及添加和删除频道 to/from 那些最终用户的频道组。
问题 2
更新文档:https://www.pubnub.com/docs/platform/security/access-control
现在这个问题更加清晰和有针对性了,它询问的是身份验证(登录)以及如何确保某人是他们所说的人以及如何处理授权(他们可以做什么,不能做什么)做)和 where/who 控制这个。
答案是,您控制身份验证(登录)以证明此人是他们所说的那样。您的登录过程会检查有效的 username/password 并且在用户记录中,您将拥有该用户的访问控制列表。这样,您就可以生成一个授权密钥,您可以授予对一个或多个频道的读取 and/or 写入权限。此授权是您的服务器调用的 PubNub 操作。授权密钥被传回客户端,客户端代码使用 pub/sub 密钥初始化 PubNub 实例,PubNub 服务器使用此授权密钥根据通道和请求的操作检查访问(订阅这个频道,发布到那个频道,等等)。如果授权密钥没有正确的访问权限,PubNub 服务器将拒绝访问(403 响应)。
所有这些还有更多内容,但这是一个好的开始。在我们的文档页面上阅读您将使用的 SDK 的 PubNub Access Manager。例如,您可以从 JavaScript SDK Access Manager docs and tutorials.
开始
问题 3
更新文档:https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels
我相信我已经用问题 1 - 渠道组回答了这个问题。从 JavaScript SDK Stream Controller (which provides Channel Group feature) docs and tutorials.
开始
我希望我已经成功地帮助您在使用 PubNub 开发非常成功的实时数据流应用程序的过程中向前迈进了几步。请回复您可能还有的任何其他问题。
*回答您的新评论:*
感谢您的后续评论。你现在问的很清楚了。
I will need to compare chat room timestamp with personal user last-read timestamp for this, so it seems that I need to listen to those channels from back-end and update user's last-reads, or to trust into the front-end, and get timestamps from a user directly
不,您不必收听服务器上的频道。是的,在客户端应用程序中,您将保留最后收到的消息的时间戳。当用户重新上线时,您可以使用此时间戳来获取客户端订阅的频道的历史记录。许多人已经成功地做到了这一点,我们将在接下来的几个月中发布一些惊人的功能,这些功能将大大简化这一过程。
pushing real-time notifications to users from the back-end. Do I need to be subscribed to all of my user channels if I want to push notes to them at any time?
您可以在任何频道上发布而无需先实际订阅。因此您的服务器可以根据需要发布到频道。
和以前一样,根据需要继续提出更多问题。
*再次提出很好的后续问题。这是我的建议*
... it makes sense to not request all of those chat rooms from DB and join via pubnub all of them, but rather implement pagination... how user can be aware of new messages that may appear in his old chat rooms?
同样,您可以使用频道组继续订阅 2 万个频道。您可以订阅 10 个频道组,每个频道组有 2K 个频道 - 但我建议将用户限制在 100 个或更少,因为这似乎足以在您的应用中施加限制。但是选择你想要的任何上限,当用户达到该限制时,强制他们先离开另一个聊天室,或者建议他们离开前 10 个最不活跃的聊天室之一,或者一些对你的应用有意义的算法。
更新文档:https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels
获取错过消息的数量确实需要获取完整的历史记录,但我们将在不久的将来提供改进的 API 以简化此操作。但是,如果用户在所有这些渠道上注册了推送通知,则设备将能够接收这些推送消息,并且您的应用程序可以在本地保留该计数。我们将很快发布一篇“如何在后台更新徽章计数”的文章。您还可以使用它来跟踪每个频道(聊天室)错过的消息数量。
For now I just want to limit the number of rooms available for users to let's say a hundred and request and join them without pagination.
更新文档:https://www.pubnub.com/docs/platform/channels/retrieve
我们确实有客户这样做而不用担心分页。他们只检索设备订阅的 100 个频道的历史记录。使用后台徽章计数更新策略,您将有优势知道在应用程序激活时从哪些渠道获取。一旦该文章发表,我将 post link link。
我正在开发一个非常有趣的 Web 应用程序项目,该项目可能会变得相当大,我有机会使用这个名为 PubNub
的方便的东西作为应用程序的主要实时引擎。
所以它是一个具有 Node.js
后端的 Web 应用程序,涉及用户之间潜在的大量聊天室以及当数据库中的某些数据更新时后端向用户发送的实时通知。
通常,使用Sockets.io
进行开发,我只会为每个用户订阅其唯一DB id 的频道,以及代表不同聊天室的频道。
这样我就可以在后端处理聊天室和身份验证,在数据库中存储一些个人通知后,我可以轻松地将它们推送到以用户 ID 命名的频道,所以如果用户在线 - 他会得到它,如果不在线 - 很好,他将在下次登录时看到它,通知已经在数据库中。从理论上讲,在 redis pub/sub.
的帮助下,这个怪物应该可以很好地水平扩展在这种情况下,让我担心 PubNub 的是可伸缩性。由于我显然不了解 PubNub 后端的黑暗角落发生了什么,我想确保该应用程序的构建方式能够准备好处理一些晦涩难懂的大量并发用户。
我的问题是,使用 PubNub
构建此类系统的最佳方法是什么?
- 我是否正确假设需要向特定用户推送通知、订阅该用户的 pubnub、推送注释和取消订阅会更好。就好像我要保持所有在线用户渠道开放一样——那么在我的服务器上使用 PubNub 而不是 websockets 是没有意义的,因为服务器无论如何都会承受所有这些打开的在线用户渠道的负载,并且应该进行扩展以保持巨大的规模它们的数量。
- 用户授权呢?在不涉及我的后端的情况下,我如何确定发布某些消息的用户将无法伪造他的个性并且与他在应用程序内部进行身份验证时完全相同?
- 通常(通过 PubNub)处理每个用户的大量聊天的最佳做法是什么?比如在应用生命周期中,每个用户可能会积累一些垃圾聊天室,其中有一些用户,虽然很长时间没有人接触过,用户懒得手动离开?
感谢您耐心阅读这面文字墙!
2021 年 12 月 5 日更新 如果您正在实施聊天应用程序,请参阅 PubNub Chat use-case documentation for full details. It has new features and UI components that are built upon the PubNub Platform。
2020 年 5 月 15 日更新 我们有 some new docs 可以更清楚地解释以下内容。
以及可应用于以下许多 questions/answers 的新功能:
- Message Actions
- Message Counts
- Batch History (multi-channel message fetch)
- Objects (Users, Channels and Memberships Metadata)
注意: 我在下面的答案中加入了上面的一些 links。
首先,让我们解决这个问题...
Thing that worries me about PubNub, in this case, is scalability. As I obviously have no insight on what is going on in PubNub backend's dark corners, I want to make sure that the app is built in a way that it will be prepared to handle some obscure enormously huge amount of simultaneous users.
还有这个...
then there is no point in PubNub instead of WebSockets on my server, as the server will be anyway under the load of all of those opened online-user channels and should be scaled just to maintain the huge quantity of them
这有点落后,因为您会使用像 PubNub 这样的服务来确保您的应用程序可以扩展以处理数百万用户。 PubNub 拥有数以千计的客户,可扩展到数百万用户和数百亿条消息。不知道 PubNub 是如何做到这一点的,您可以自由地实施应用程序的业务逻辑。
但我想我明白你在说什么。您的印象是您的服务器必须参与每个用户的每个聊天室交互,但这只是部分正确。大多数情况下,您的服务器将用于身份验证、一些订阅维护(可选),并可能根据需要(取决于您的要求)向一个、多个或所有最终用户发送消息。
这里有一些尝试来回答你的问题,尽管它们有点到处都是,所以我会尽力回答我认为你在问的问题。
问题 1
这个问题似乎是针对维持大量的频道订阅和它的可扩展性。
一般来说,每个最终用户都会初始化 PubNub 并订阅他们需要收听的频道,并发布到他们需要发送消息的频道。通常,他们发布的频道(我假设是您的聊天室)与他们订阅的频道相同,但它们是不同类型的用例。您可以一次订阅数千个频道(每个客户最多 20K)。如果您使用 WebSockets 做到这一点,您将如何将其扩展到数百万用户?您将实施和操作(以扩展)类似于 PubNub 的东西(不容易且不便宜)。
现在,如果用户订阅了一堆聊天室频道,但其中一些或许多频道已过时(用户有一段时间没有查看或 posted),您可以在上面添加一些代码您的服务器(或客户端)监控用户的 activity 并从那些陈旧的频道中取消订阅。这可以使用 channels groups。每个最终用户都有自己的频道组,其中包含他们正在收听的所有频道。以及客户端代码或服务器代码以及添加和删除频道 to/from 那些最终用户的频道组。
问题 2
更新文档:https://www.pubnub.com/docs/platform/security/access-control
现在这个问题更加清晰和有针对性了,它询问的是身份验证(登录)以及如何确保某人是他们所说的人以及如何处理授权(他们可以做什么,不能做什么)做)和 where/who 控制这个。
答案是,您控制身份验证(登录)以证明此人是他们所说的那样。您的登录过程会检查有效的 username/password 并且在用户记录中,您将拥有该用户的访问控制列表。这样,您就可以生成一个授权密钥,您可以授予对一个或多个频道的读取 and/or 写入权限。此授权是您的服务器调用的 PubNub 操作。授权密钥被传回客户端,客户端代码使用 pub/sub 密钥初始化 PubNub 实例,PubNub 服务器使用此授权密钥根据通道和请求的操作检查访问(订阅这个频道,发布到那个频道,等等)。如果授权密钥没有正确的访问权限,PubNub 服务器将拒绝访问(403 响应)。
所有这些还有更多内容,但这是一个好的开始。在我们的文档页面上阅读您将使用的 SDK 的 PubNub Access Manager。例如,您可以从 JavaScript SDK Access Manager docs and tutorials.
开始问题 3
更新文档:https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels
我相信我已经用问题 1 - 渠道组回答了这个问题。从 JavaScript SDK Stream Controller (which provides Channel Group feature) docs and tutorials.
开始我希望我已经成功地帮助您在使用 PubNub 开发非常成功的实时数据流应用程序的过程中向前迈进了几步。请回复您可能还有的任何其他问题。
*回答您的新评论:*
感谢您的后续评论。你现在问的很清楚了。
I will need to compare chat room timestamp with personal user last-read timestamp for this, so it seems that I need to listen to those channels from back-end and update user's last-reads, or to trust into the front-end, and get timestamps from a user directly
不,您不必收听服务器上的频道。是的,在客户端应用程序中,您将保留最后收到的消息的时间戳。当用户重新上线时,您可以使用此时间戳来获取客户端订阅的频道的历史记录。许多人已经成功地做到了这一点,我们将在接下来的几个月中发布一些惊人的功能,这些功能将大大简化这一过程。
pushing real-time notifications to users from the back-end. Do I need to be subscribed to all of my user channels if I want to push notes to them at any time?
您可以在任何频道上发布而无需先实际订阅。因此您的服务器可以根据需要发布到频道。
和以前一样,根据需要继续提出更多问题。
*再次提出很好的后续问题。这是我的建议*
... it makes sense to not request all of those chat rooms from DB and join via pubnub all of them, but rather implement pagination... how user can be aware of new messages that may appear in his old chat rooms?
同样,您可以使用频道组继续订阅 2 万个频道。您可以订阅 10 个频道组,每个频道组有 2K 个频道 - 但我建议将用户限制在 100 个或更少,因为这似乎足以在您的应用中施加限制。但是选择你想要的任何上限,当用户达到该限制时,强制他们先离开另一个聊天室,或者建议他们离开前 10 个最不活跃的聊天室之一,或者一些对你的应用有意义的算法。
更新文档:https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels
获取错过消息的数量确实需要获取完整的历史记录,但我们将在不久的将来提供改进的 API 以简化此操作。但是,如果用户在所有这些渠道上注册了推送通知,则设备将能够接收这些推送消息,并且您的应用程序可以在本地保留该计数。我们将很快发布一篇“如何在后台更新徽章计数”的文章。您还可以使用它来跟踪每个频道(聊天室)错过的消息数量。
For now I just want to limit the number of rooms available for users to let's say a hundred and request and join them without pagination.
更新文档:https://www.pubnub.com/docs/platform/channels/retrieve
我们确实有客户这样做而不用担心分页。他们只检索设备订阅的 100 个频道的历史记录。使用后台徽章计数更新策略,您将有优势知道在应用程序激活时从哪些渠道获取。一旦该文章发表,我将 post link link。