18

我正在使用 PHP 和 MySQL。

我刚刚注册了 pubnub 推送 API,并使用 Pubnub 提供的 PHP 推送 API 成功发出了我的第一个推送通知。我是这种实时技术的新手,所以我提出了一些我觉得难以理解的问题。我用谷歌搜索了很多次,并在stackoverflow上进行了搜索。我在其他地方没有得到任何相关的建议或问题,所以我在这里写下我的问题,寻求您的建议和专业知识的帮助。

Pubnub 表示,为每个客户创建两个以上的频道并不是一件好事。因此,在我的应用程序中,我需要创建两个以上的频道来收听我网站上各处发生的通知,但我将为每个登录用户使用两个频道,正如 Pubnub 建议的那样。

  1. 登录用户收听 Channel1-Public
  2. 登录的用户收听私有的 UsersOwnDynamic-Channel 以接收相关的通知,并且只针对他。

仅供参考:PubNub 中的此链接说有关创建 LongChannel 名称以避免 Channel Snooping

我的问题如下:
A. 每次登录网站时,我是否总是需要创建一个新的私人动态频道名称。如果是这样,其他用户如何知道如何向我的私人频道发送通知。或者,我是否只需要在数据库表中存储一个静态频道名称,以便其他经过身份验证的用户查询该表并获取我的私人频道向我发送通知的名称。如果是这样,你不认为如果黑客掌握了某些用户的一些私人频道名称,他们将能够收听该频道吗?

BI 正在使用 PHP 和 MySQL,所以我仍然无法想出办法或想出一个解决方案来将消息发送到另一个用户的私人频道。
让我们以一个简单的好友请求系统为例。
- UserA 向 UserB 发送好友请求。
- UserB 正在收听他自己的名为 DynamicPrivateChannelB 的动态私人频道名称
(UserA 将如何找到 UserB 的私人频道名称?我认为唯一的方法是 UserB 的私人频道应该存储在每个数据库表中登录用户查询。我的想法是否正确?)

<?php 

    //first way. How can i possibly achieve this.
    $sqlquery = "sent friend request from userA to userB"; 
    require('Pubnub.php'); 
    $pubnub = new Pubnub( 'pubkey', 'subkey' );
    $pubnub->publish( array(
        'channel' => 'how do i find the private channel name for userB to sent this notification?', 
                    'message' => array('friend_request' => 'A friend request') ) 
                    );

  //2nd way ? Is this the right way ?
    $sqlquery = "sent friend request from userA to userB"; 
    $privatechannelofuserB = "get the channel name of userB from the db table";
    require('Pubnub.php'); 
    $pubnub = new Pubnub( 'pubkey', 'subkey' );
    $pubnub->publish( array(
        'channel' => '$privatechannelofuserB', 
                    'message' => array('friend_request' => 'A friend request') ) 
                    );
?>

C. 如果我们总是生成动态私有频道名称,存储在数据库表中,每当生成新的动态频道名称时进行更新。我认为这会导致问题,因为某些消息不会被传递,因为新的动态私人频道名称会替换旧的。

D. 所以,我有很多通知要发送到一个单一的频道,比如新朋友请求、新私人消息回复、新礼物请求和许多其他类似的。如何将所有这些数据发送到通道以及如何找出和解析传入的新通知数据。我知道 JSON 是发送的格式,但我不确定发送的格式。

根据此链接,单个 Pubnub 频道最多只能包含 100 条消息。这是否意味着如果 200 条消息同时发送到单个通道,则前 100 条消息被传递,其余消息在队列中?如果 10,000 条消息同时发送到一个频道会怎么样?是否所有剩余的消息都留在队列中?如果是这样,它如何实时交付给订户?

让我给出另一个我想要实现的简单场景。

  • UserA已通过身份验证并登录到网站。
  • UserA生成自己的动态频道名称,UserAx732dsw3efsdfsdfsdf
  • UserA开始收听他新创建的频道UserAx732dsw3efsdfsdfsdf
    (现在​​,userA 应该开始接收来自其他人的消息)


- UserB向userA发送私人消息。
(现在,只有 userA 应该在他的私人频道上收到关于新私人消息的通知,userB 或系统如何找到 频道名称UserAx732dsw3efsdfsdfsdf因为,这是一个由userA动态生成的私人频道,系统userB都没有访问过同样的事情也发生在userB 身上,如果userB应该被任何其他实体或系统再次通知,应该有办法找出userB的动态频道名称。

另一个问题是这种情况是,如果用户每次登录网站时都动态生成频道名称。发送到动态通道的所有消息会发生什么?pubnub 是否将所有创建的频道名称保存在其服务器上?有没有什么方法可以让系统或用户找出频道名称是否仍然是自己的,并且至少有一个用户正在收听频道?

我很想知道这一点,因为我有以下概念:

  • UserA在凌晨 1点登录网站时创建了dynamicChannelA
  • UserA 开始收到大量通知推送到他的动态频道dynamicChannelA
  • 现在,UserA在凌晨 1:30从网站注销,许多其他仍在向他的dynamicChannelA推送通知的用户会发生什么,因为当UserA下次 登录网站时,UserA将监听不同的动态频道名称。UserA不会收听他以前的频道dynamicChannelA


我正在考虑使用从数据库表中检索特定用户的频道名称的方法。是否有任何方法或方法可以防止未经授权的频道订阅?因为任何人都可以订阅频道名称,只要他们有订阅密钥和频道名称,无论频道名称有多长。我只是好奇,因为所有订阅都发生在客户端,并且订阅密钥和频道名称是可见的。

4

1 回答 1

30

没有一种方法可以解决您遇到的问题。我们的客户使用了各种各样的设计模式来处理它们。我自己在构建 PubNub 应用程序时遇到过这种类型的事情,我会尽可能地帮助你。

Pubnub 表示,为每个客户创建两个以上的频道并不是一件好事。因此,在我的应用程序中,我需要创建两个以上的频道来收听我网站上各处发生的通知,但我将为每个登录用户使用两个频道,正如 Pubnub 建议的那样。

登录的用户收听 Channel1-Public 登录的用户收听私有的 UsersOwnDynamic-Channel 以接收相关的通知,并且只针对他。

这是一个很好的方法,我们的许多大规模客户都是这样做的。一个全球频道和一个私人的、仅限用户的频道。

一个。

每次登录网站时,我总是需要创建一个新的私人动态频道名称吗?

不一定,虽然这是一个好方法。您可以PUBNUB.uuid()在客户端的 JavaScript 中使用来执行此操作。或者,使用 PHP 在服务器端生成它并将其呈现给客户端。也许您可以将其设置为 cookie,以便客户端始终可以访问它。

如果是这样,其他用户怎么知道如何向我的私人频道发送通知。

他们可以从 PHP 服务器获取 id;通过他们正在收听的全局频道或用户自己的私人频道。

或者,我是否只需要在数据库表中存储一个静态频道名称,以便其他经过身份验证的用户查询该表并获取我的私人频道名称以向我发送通知。

你也可以这样做。您可能拥有用户可以发送的全局频道,而不是他们正在收听的全局频道。只有服务器具有订阅密钥。因此,经过身份验证的用户向服务器发送一条消息,告诉它“我需要适当的用户密钥”,然后服务器进行查询并在该用户的私人频道上发回一条消息。

如果是这样,你不认为如果黑客掌握了某些用户的一些私人频道名称,他们将能够收听该频道吗?

如果您在全局发送通道上保留订阅密钥,则只有服务器可以看到该通道上的聊天。

B.

我使用 PHP 和 mysql,所以我仍然想不出办法或想出一个解决方案来将消息发送到另一个用户的私人频道。让我们以一个简单的好友请求系统为例。- UserA 向 UserB 发送好友请求。- UserB 正在收听他自己的名为 DynamicPrivateChannelB 的动态私人频道名称(UserA 将如何找到 UserB 的私人频道名称?我认为唯一的方法是 UserB 的私人频道应该存储在每个数据库表中登录用户查询。我的想法是否正确?)

这与您之前的问题非常相似。没有一种方法可以做到这一点,但我上面概述的设计模式应该可以工作。回顾一下这个设计模式:

服务器端

  • 在 Global-user-send-channel 上侦听用户消息。服务器是唯一拥有此订阅密钥的实体
  • 可以查询db获取user-ids,然后随意发送到各个ids
  • 也可以在所有客户端都在监听的 Global-user-receive-channel 上发送。服务器是唯一拥有此发布密钥的实体。

客户端

  • 在 Global-user-receive-channel 上收听。这就是它获得大量服务器广播的方式。无法在此频道上发送(只有订阅密钥)
  • 在 Global-user-send-channel 上发送服务器消息。无法在此频道上接收(只有发布密钥)
  • 收听私人用户频道。这就是用户获取私人消息的方式。它还可以将其用于客户端到客户端的通信。
  • 通过在所有私人消息中附加一个存储在服务器上并在初始页面加载期间提供的每个用户的私有密钥来防止滥用。这样,客户端就知道声称来自服务器的消息是否合法。

C。

如果我们总是生成动态私有频道名称,存储在数据库表中,每当生成新的动态频道名称时进行更新。我认为这会导致问题,因为某些消息不会被传递,因为新的动态私人频道名称会替换旧的。

如果您在生成新频道名称时很小心,这应该不是问题。请记住,客户总是可以在 Global-user-send-channel 上说“嘿,我在这里!这是我的身份证。让我更新'。我通常将我的应用程序设计为让客户每 30 秒左右自动喊出这一点。

D.

所以,我有许多通知要发送到单个频道,例如新朋友请求、新私人消息回复、新礼物请求和许多其他类似的通知。我如何将所有这些数据发送到通道以及如何找出和解析传入的新通知数据。我知道 JSON 是发送的格式,但我不确定发送的格式。

JSON 适合发送和接收。我这样做的方法是拥有一个名为“name”的属性,它定义了它是什么类型的消息。例如:

{
    "id"   : "blah_blah_unique_id",    // sender_client_id 
    "name" : "friend_request",         // type of message
    "data" : {                         // the data itself
               "requested_friend_id" : "blah_blah_some_other_unique_id" 
             }
}

您实际上可以使用您想要的任何格式,但是当它通过 PubNub 推送时,我们会将它包装在 JSON 中(通常这意味着只用引号括起来)。

希望这可以帮助!

新问题

根据此链接,单个 Pubnub 频道最多只能包含 100 条消息。这是否意味着如果 200 条消息同时发送到单个通道,则前 100 条消息被传递,其余消息在队列中?如果 10,000 条消息同时发送到一个频道会怎么样?是否所有剩余的消息都留在队列中?如果是这样,它如何实时交付给订户?

100 条消息限制与 PubNub.history 相关。如果有人订阅了 200 条消息,他们将收到全部 200 条消息。

(现在,只有 userA 应该在他的私人频道上收到关于新私人消息的通知,userB 或系统如何找到频道名称 UserAx732dsw3efsdfsdfsdf 因为,这是一个由 userA 动态生成的私人频道,系统或 userB 都没有访问过同样的事情也发生在 userB 身上,如果 userB 应该被任何其他实体或系统再次通知,应该有办法找出 userB 的动态频道名称。

这个问题没有万能的解决方案,但我要做的是让服务器在页面加载时生成该唯一 ID,并在您的初始 HTTP 请求中将其呈现给客户端。

另一个问题是这种情况是,如果用户每次登录网站时都动态生成频道名称。发送到动态通道的所有消息会发生什么?pubnub 是否将所有创建的频道名称保存在其服务器上?

您不必每次都动态生成。您可以....但是您还设置了具有该唯一 ID 的 cookie,或者将其从数据库中提取并在页面加载时将其呈现给客户端(这就是我要做的)。我们不保存频道名称。

有没有什么方法可以让系统或用户找出频道名称是否仍然是自己的,并且至少有一个用户正在收听频道?

不是开箱即用,但您可以轻松实现。只需让您的服务器发送一个 ping 并将您的客户端设置为在他们正在收听时始终响应 ping。

现在,UserA 在凌晨 1 点 30 分从网站退出,许多其他仍在向他的 dynamicChannelA 推送通知的用户会发生什么,因为当 UserA 下次登录网站时,UserA 将监听不同的动态频道名称.UserA 不会收听他之前的频道 dynamicChannelA 。

您可以防止这种情况的方法是定期(每 30 秒?)来自服务器的 ping,如果用户仍然在那里,谁可以跟踪。顺便说一句,在接下来的几个月里,我们将推出一个在线状态 API 来自动执行此操作。

我正在考虑使用从数据库表中检索特定用户的频道名称的方法。是否有任何方法或方法可以防止未经授权的频道订阅?因为任何人都可以订阅频道名称,只要他们有订阅密钥和频道名称,无论频道名称有多长。我只是好奇,因为所有订阅都发生在客户端并且订阅密钥和频道名称是可见的

主要方式是战略性地保留发布/订阅密钥。你是对的,任何有适当细节的人都可以收听——这是纯客户端系统的一个大问题。目前,您必须想出一些创造性的方法来解决它。

于 2012-06-04T18:48:17.703 回答