javascript - 来自后端的实时用户通知,具有PubNub,可伸缩性和超过9000个聊天室

标签 javascript node.js websocket pubnub

我正在开发一个非常有趣的Web应用程序项目,该项目可能会变得很大,并且有机会尝试使用名为PubNub的便捷工具作为应用程序的主要实时引擎。

因此,这是一个具有Node.js后端的Web应用程序,涉及到用户之间潜在的大量聊天室,以及在更新数据库中的某些数据时由后端发送给用户的实时通知。

通常,使用Sockets.io进行开发,我将只订阅每个用户的唯一DB ID channel ,并订阅代表不同聊天室的 channel 。

这样,我可以处理后端的聊天室和身份验证,并且在将一些个人通知存储在数据库中之后,我可以轻松地将其推送到由用户ID命名的 channel ,因此,如果用户在线-他可以(如果可以)-很好,他会看到的下次登录时,通知已存在于数据库中。从理论上讲,这种怪物应该在redis pub/sub的帮助下在水平方向上很好地缩放。

在这种情况下,令我担心的PubNub是可伸缩性。由于我显然对PubNub后端的黑角中所发生的事情一无所知,因此我想确保该应用程序的构建方式使其可以处理一些晦涩难懂的大量同时用户。

我的问题是,用PubNub构建这样的系统的最佳方法是什么?

  • 我是否正确地假设是,需要向特定用户推送通知来订阅该用户的发布,推送注释和退订会更好。好像我将所有在线用户 channel 保持打开状态一样,那么服务器上的PubNub而不是websockets毫无意义,因为服务器无论如何都将承受所有打开的在线用户 channel 的负载,因此应进行扩展以保持庞大的在线用户 channel 他们的数量。
  • 用户授权如何?在不涉及后端的情况下,我如何确定发布某些消息的用户将无法伪造自己的个性,并且与在应用程序内部进行身份验证的身份完全相同?
  • 通常(以及通过PubNub)解决每个用户大量聊天的最佳实践是什么?可以这么说,在应用程序生命周期中,每个用户都可能积累了相当数量的垃圾聊天室,其中有些用户在其中,尽管很长一段时间都没有人碰过它,而用户却懒得手动离开它?

  • 感谢您耐心阅读本文墙!

    最佳答案

    更新于2020年5月15日
    我们有some new docs,它将以更清晰的方式解释下面的许多内容。

    以及可应用于以下许多问题/答案的新功能:

  • Message Actions
  • Message Counts
  • Batch History (multi-channel message fetch)
  • Objects (Users, Channels and Memberships Metadata)-在此等待对象v2(即将推出)

  • 注意:我在下面的答案中撒了一些上面的链接。

    首先,让我们解决这个问题...

    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 app is built in the 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 server will be anyway under load of all of those opened online-user channels and should be scaled just to maintain huge quantity of them



    这有点倒退,因为您将使用诸如PubNub之类的服务来确保您的应用程序可扩展以处理数百万个用户。 PubNub拥有成千上万的客户,可扩展到数百万用户和1000亿条消息。不知道PubNub如何做到这一点使您可以释放应用程序的业务逻辑。

    但是我想我明白你的意思。您的印象是您的服务器必须参与每个用户的每次聊天室交互,但这只是部分正确。通常,您的服务器将用于身份验证,某些订阅维护(可选),并可能根据需要(取决于您的要求)用于向一个,许多或所有最终用户发送消息。

    尽管有些杂乱无章,但是这里还是尝试回答您的问题,因此,我将尽我所能回答您认为的问题。

    问题1

    这个问题似乎是针对维护 channel 的大量订阅及其可扩展性。

    一般而言,每个最终用户都会初始化PubNub并订阅他们需要收听的 channel ,并发布到他们需要在其上发送消息的 channel 。通常,它们发布的 channel (假设是您的聊天室)使用的是相同的 channel ,但是存在不同的用例类型。您一次可以订阅数千个 channel (每个客户端最多可订阅2万个 channel )。如果使用WebSockets完成此操作,您将如何扩展到数百万用户?您将实现和操作(按比例缩放)类似于PubNub的东西(既不容易也不便宜)。

    现在,如果用户订阅了许多聊天室 channel ,但是有些或许多是陈旧的(用户已经一段时间未查看或发布),则服务器(或客户端)上可能会有一些代码可以监视用户的 Activity ,并从这些过时的 channel 退订他们。使用channels groups这是可能的。每个最终用户将拥有自己的 channel 组,其中包含他们正在收听的所有 channel 。以及客户端代码或服务器代码,并向这些最终用户的 channel 组添加 channel 或从这些最终用户的 channel 组中删除 channel 。

    问题2

    更新了DOCS :https://www.pubnub.com/docs/platform/security/access-control

    现在,这个问题更加清晰和集中了,它在询问有关身份验证(登录)以及如何确保某人的身份,以及如何处理授权(他们可以做什么和不可以做什么)以及在哪里/由谁控制这方面的问题。

    答案是,您可以控制身份验证(登录)以证明此人就是他们所说的。您的登录过程将检查有效的用户名/密码,并且在用户记录中,您将获得该用户的访问控制列表。这样,您将生成一个auth-key,该auth-key授予对一个或多个 channel 的读取和/或写入访问权限。此授予是服务器调用的PubNub操作。 auth-key传递回客户端,并且客户端代码使用pub/sub key 初始化PubNub实例,PubNub服务器使用该auth-key根据 channel 和所请求的操作(访问此 channel )检查访问权限,发布到该 channel 等)。如果auth-key没有正确的访问权限,则PubNub服务器将拒绝访问(403响应)。

    所有这些还有更多,但这是一个好的开始。在我们的文档页面上,使用PubNub Access Manager for SDK进行阅读。例如,您可以从JavaScript SDK Access Manager docs and tutorials开始。

    问题3

    更新了DOCS :https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels

    我相信我对问题1- channel 组的回答足够充分。从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 in to front end, and get timestamps from a user directly



    不,您不必监听服务器上的 channel 。是的,从客户端应用程序,您将保留最后收到的消息的时间戳。当用户重新联机时,您可以使用此时间戳来获取客户端订阅的 channel 的历史记录。许多人已经成功地做到了这一点,我们将在 future 几个月内发布一些惊人的功能,这些功能将大大简化这一过程。

    pushing realtime notifications to users from 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



    您可以在任何 channel 上发布,而无需先实际订阅。因此,您的服务器可以根据需要发布到 channel 。

    和以前一样,继续提出您需要的更多问题。

    再次进行重大跟进提问。这是我的建议

    ... it makes since 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 a new messages that may appear in his old chat rooms?



    同样,您可以使用 channel 组继续订阅2万个 channel 。您可以订阅10个 channel 组,每个 channel 组2K个 channel -但我建议仅将用户限制为100个或更少,因为这似乎足以限制您的应用程序。但是,请选择所需的上限,并在用户达到该上限时,强制他们首先离开另一个聊天室,或者建议他们离开最不活跃的前十名之一,或者采用对您的应用有意义的算法。

    更新了DOCS :https://www.pubnub.com/docs/platform/channels/receive#subscribe-to-channels

    获取遗漏消息的数量确实需要完整的历史记录获取,但是我们将提供改进的API,以在不久的将来使此操作更简单。但是,如果在所有这些 channel 上为用户注册了推送通知,则该设备将能够接收这些推送消息,并且您的应用程序可以将该计数保留在本地。我们将很快发布一篇“如何在后台更新徽章计数”的文章。您还可以使用它来跟踪每个 channel (聊天室)中错过的消息数。

    For now i just want to limit amount of rooms available for users to let's say a hundred and request and join them without pagination.



    更新了DOCS :https://www.pubnub.com/docs/platform/channels/retrieve

    我们确实有这样做的客户而不必担心分页。他们只是检索设备已订阅的100个 channel 上的历史记录。使用后台徽章计数更新器技术,您将有一个优势,当应用程序启动时,知道从哪个 channel 获取信息。发布该文章后,我将在此处发布该文章的链接。

    关于javascript - 来自后端的实时用户通知,具有PubNub,可伸缩性和超过9000个聊天室,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33587107/

    相关文章:

    Javascript 将格式从循环更改为数组格式

    node.js - 错误: property map doesn't exist on type 'Observable<Response>'

    javascript - 为什么我无法从导出函数获取数据

    websocket - 如何使用 netty 保护 websockets

    javascript - Phonegap 应用程序 - Pusher 和 PubNub 的替代品

    javascript - 隐藏具有特定属性的元素

    javascript - 协调 dragmove 不超过 30 FPS

    javascript - 如何链接到具有特定过滤器的投资组合页面?

    angularjs - 在 AngularJS 中使用重复键迭代 json 响应

    python - 异步函数中的变量未在 while-True 循环中重新计算