18

私はPHPとMySQLを使用しています。

pubnub プッシュ API にサインアップしたばかりで、Pubnub が提供する PHP プッシュ API を使用して最初のプッシュ通知を正常に作成しました。私はこのリアルタイム テクノロジに慣れていないので、自分で理解するのが難しいと思ういくつかの質問を思いつきました。私は何度もグーグルで検索し、stackoverflow全体を検索しました。他に関連する提案や質問が得られなかったので、ここに質問を書き留めて、アドバイスや専門知識の助けを求めています.

Pubnub は、クライアントごとに 2 つ以上のチャネルを作成するのは良くないと述べています。したがって、私のアプリケーションでは、Web サイトのどこでも発生する通知をリッスンするために 2 つ以上のチャネルを作成する必要がありますが、Pubnub が提案したように、ログインしているユーザーごとに 2 つのチャネルを使用します。

  1. ログインしたユーザーは Channel1-Public をリッスンします
  2. ログインしたユーザーは、プライベートの UsersOwnDynamic-Channel をリッスンして、関連する通知を受け取ります。

参考までに: PubNub のこのリンクは、チャネル スヌーピングを回避するために LongChannel 名を作成することについて述べています。

私の質問は次のとおりです
。 A. Web サイトにログインするたびに、常に新しいプライベート動的チャネル名を作成する必要がありますか。もしそうなら、他のユーザーが私のプライベート チャネルに通知を送信する方法を知るにはどうすればよいでしょうか。または、他の認証されたユーザーがテーブルをクエリして私のプライベート チャネルを取得できるように、データベース テーブルに静的チャネル名を 1 つだけ格納する必要がありますか?通知を送信する名前。この場合、ハッカーが特定のユーザーのプライベート チャンネル名を入手すれば、そのチャンネルを聞くことができると思いませんか?

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. そのため、新しい友達のリクエスト、新しいプライベート メッセージの返信、新しいギフトのリクエストなど、1 つのチャネルに送信する通知がたくさんあります。これらすべてのデータをチャネルに送信する方法と、受信した新しい通知データを見つけて解析する方法。JSON が送信する形式であることは知っていますが、送信の形式についてはわかりません。

このリンクによると、単一の Pubnub チャネルには最大 100 個のメッセージしか含めることができません。一度に 200 件のメッセージが 1 つのチャネルに届いた場合、最初の 100 件が配信され、残りはキューに入れられるということですか? 一度に 10,000 件のメッセージが 1 つのチャネルに届いたらどうでしょうか。残りのメッセージはすべてキューに残りますか? もしそうなら、それはどのようにしてサブスクライバーにリアルタイムで配信されますか?

私が達成しようとしている別の簡単なシナリオを挙げましょう。

  • UserAは認証され、Web サイトにログインします。
  • UserAは、独自の動的チャネル名UserAx732dsw3efsdfsdfsdfを生成します。
  • UserAは、新しく作成したチャネルUserAx732dsw3efsdfsdfsdf
    のリッスンを開始します (これで、userA は他のユーザーからのメッセージの受信を開始するはずです)


- UserBがuserAにプライベート メッセージを送信します。
(ここで、新しいプライベート メッセージについてプライベート チャネルで通知されるのは userA だけです。userBまたは システム、チャネル名UserAx732dsw3efsdfsdfsdfをどのように見つけることができます?これと同じことがuserBにも起こっています. userBが他のエンティティまたはシステムから再度通知を受ける必要がある場合は、 userBの動的チャネル名を見つける方法が必要です.

別の問題は、このシナリオは、ユーザーが Web サイトにログインするたびにチャネル名を動的に生成している場合です。動的チャネルに送信されたすべてのメッセージはどうなりますか? pubnub は作成したすべてのチャンネル名をサーバーに保存しますか? チャンネル名がまだ所有されていて、少なくとも 1 人のユーザーがそのチャンネルを聞いているかどうかをシステムまたはユーザーが確認できる方法はありますか?

私が持っている次の概念のため、これを知りたいと思っています。

  • UserAは、午前 1時にWeb サイトにログインすると、dynamicChannelAを作成します。
  • UserA が自分の動的チャネルに大量の通知プッシュアウトを受け取り始めますdynamicChannelA
  • ここで、UserAは午前 1 時 30 分に Web サイトからログアウトします。ユーザー A が次に Web サイトにログインするまでに、UserAは別の動的チャネルをリッスンするため、動的チャネル Aにまだ通知をプッシュしている他の多くのユーザーはどうなるでしょうか。チャンネル名。UserAは、以前のチャネルdynamicChannelAをリッスンしません。


データベーステーブルから特定のユーザーのチャンネル名を取得する方法を考えています。チャンネルの不正な購読を防ぐ方法または方法はありますか? チャンネル名の長さに関係なく、サブスクライブキーとチャンネル名があれば、誰でもチャンネル名にサブスクライブできるからです。すべてのサブスクリプションはクライアント側で行われ、サブスクリプション キーとチャネル名が表示されるので、ちょっと興味があります。

4

1 に答える 1

30

遭遇した問題に対処する唯一の方法はありません。私たちの顧客は、さまざまな設計パターンを使用してそれらに対処してきました。私自身、PubNub アプリを構築する際にこの種の作業に遭遇したことがあります。できる限りお手伝いします。

Pubnub は、クライアントごとに 2 つ以上のチャネルを作成するのは良くないと述べています。したがって、私のアプリケーションでは、Web サイトのどこでも発生する通知をリッスンするために 2 つ以上のチャネルを作成する必要がありますが、Pubnub が提案したように、ログインしているユーザーごとに 2 つのチャネルを使用します。

ログインしたユーザーは、Channel1-Public をリッスンします ログインしたユーザーは、Private UsersOwnDynamic-Channel をリッスンして、関連する通知を受信します。

これは良い方法であり、大規模な顧客の多くが行っている方法です。グローバル チャネルとプライベートなユーザー専用チャネル。

A.

Web サイトにログインするたびに、常に新しいプライベート動的チャネル名を作成する必要がありますか?

必ずしもそうではありませんが、これは良い方法です。PUBNUB.uuid()これを行うには、クライアント側の JavaScript で使用できます。または、PHP を使用してサーバー側で生成し、クライアントにレンダリングします。クライアントが常にアクセスできるように、Cookie として設定することもできます。

もしそうなら、他のユーザーは私のプライベートチャンネルに通知を送信する方法をどのように知っていますか.

PHP サーバーから ID を取得できます。グローバルチャンネルまたはユーザーが聞いているプラ​​イベートチャンネルのいずれかを介して。

または、データベース テーブルに静的チャネル名を 1 つだけ格納する必要があるので、他の認証されたユーザーがテーブルをクエリし、プライベート チャネル名を取得して通知を送信できるようにします。

この方法でもできます。ユーザーが送信できるグローバル チャネルが、ユーザーが聞いているグローバル チャネルと異なる場合があります。そのサブスクライブ キーを持っているのはサーバーだけです。したがって、認証されたユーザーは、「適切なユーザーキーが必要です」というメッセージをサーバーに送信し、サーバーはクエリを実行して、そのユーザーのプライベートチャネルでメッセージを返信します。

この場合、ハッカーが特定のユーザーのプライベート チャンネル名を入手すれば、そのチャンネルを聞くことができると思いませんか?

グローバル送信チャネルでサブスクライブ キーを差し控えると、サーバーだけがそのチャネルのチャットを見ることができます。

B.

私はPHPとmysqlを使用しているので、別のユーザーのプライベートチャネルにメッセージを送信する方法を考えたり、解決策を思いついたりすることはできません。簡単な友達リクエストシステムの例を見てみましょう。- UserA が UserB に友達リクエストを送信します。- UserB は、DynamicPrivateChannelB と呼ばれる自分自身の動的プライベート チャネル名をリッスンしています (UserA は、プライベートである UserB のチャネル名をどのように見つけるのでしょうか?私は、これに対する唯一の方法は、UserB のプライベート チャネルをすべてのデータベース テーブルに格納することだと考えています。ログインしているユーザーがクエリを実行します。私は正しい方法で考えていますか?)

これはあなたの前の質問と非常によく似ています。これを行う方法は 1 つではありませんが、上で概説した設計パターンが機能するはずです。この設計パターンを要約すると、次のようになります。

サーバ側

  • ユーザー メッセージを Global-user-send-channel でリッスンします。サーバーは、このサブスクライブ キーを持つ唯一のエンティティです。
  • ユーザー ID を取得するために db にクエリを実行し、さまざまな ID に自由に送信できます
  • すべてのクライアントがリッスンしている Global-user-receive-channel で送信することもできます。サーバーは、この公開キーを持つ唯一のエンティティです。

クライアント側

  • Global-user-receive-channel でリッスンします。これは、大量のサーバー ブロードキャストを取得する方法です。このチャネルでは送信できません (サブスクライブ キーしかありません)
  • Global-user-send-channel でサーバー メッセージを送信します。このチャネルでは受信できません (公開キーしかありません)
  • プライベート ユーザー チャネルでリッスンします。これは、ユーザーがプライベート メッセージを取得する方法です。これは、クライアント間の通信にも使用できます。
  • すべてのプライベート メッセージに、サーバーに保存され、最初のページ読み込み時に提供されるユーザーごとのプライベート キーを追加することで、悪用を防ぎます。そうすれば、クライアントは、サーバーからのものであると主張するメッセージが正当であるかどうかを知ることができます。

C.

動的なプライベート チャネル名を常に生成し、データベース テーブルに格納し、新しい動的チャネル名が生成されるたびに更新する場合。新しい動的プライベート チャネル名が古い名前に置き換わるため、一部のメッセージが配信されないため、問題が発生すると思います。

新しいチャンネル名をいつ生成するかについて注意を払っていれば、これは問題にはなりません。クライアントはいつでも Global-user-send-channel で「ねえ、私はここにいます!」と言うことができることに注意してください。これは私のIDです。何かあったらすぐ知らせて'。私は通常、クライアントが 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 でラップされます (通常は引用符で囲まれることを意味します)。

お役に立てれば!

新しい質問

このリンクによると、1 つの Pubnub チャネルには最大 100 個のメッセージしか含めることができません。一度に 200 件のメッセージが 1 つのチャネルに届いた場合、最初の 100 件が配信され、残りはキューに入れられるということですか? 一度に 10,000 件のメッセージが 1 つのチャネルに届いたらどうでしょうか。残りのメッセージはすべてキューに残りますか? もしそうなら、それはどのようにしてサブスクライバーにリアルタイムで配信されますか?

100 件のメッセージ制限は、PubNub.history に関するものです。誰かが購読していて、200 件のメッセージが届いた場合、その人は 200 件のメッセージすべてを受け取ります。

(ここで、userA のみが新しいプライベート メッセージについてプライベート チャネルで通知を受け取る必要があります。userB またはシステムは、チャネル名 UserAx732dsw3efsdfsdfsdf をどのように見つけることができますか?これと同じことが userB にも起こっています. userB が他のエンティティまたはシステムから再度通知を受ける必要がある場合は、 userB の動的チャネル名を見つける方法が必要です.

この質問に対する万能の解決策はありませんが、私がしたいことは、サーバーがページの読み込み時にその一意の ID を生成し、最初の HTTP 要求でクライアントにレンダリングすることです。

別の問題は、このシナリオは、ユーザーが Web サイトにログインするたびにチャネル名を動的に生成している場合です。動的チャネルに送信されたすべてのメッセージはどうなりますか? pubnub は作成したすべてのチャンネル名をサーバーに保存しますか?

毎回動的に生成する必要はありません。できます....しかし、その一意のIDでCookieを設定するか、データベースから取得して、ページの読み込み時にクライアントにレンダリングします(それが私がすることです)。チャンネル名は保存されません。

チャンネル名がまだ所有されていて、少なくとも 1 人のユーザーがそのチャンネルを聞いているかどうかをシステムまたはユーザーが確認できる方法はありますか?

すぐに使えるわけではありませんが、これは簡単に実装できます。サーバーがpingを送信し、クライアントがリッスンしている場合は常にpingに応答するように設定するだけです.

ここで、UserA は午前 1 時 30 分に Web サイトからログアウトします。ユーザー A が次に Web サイトにログインするまでに、UserA は別の動的チャネルをリッスンするため、まだ動的チャネル A に通知をプッシュしている他の多くのユーザーはどうなるでしょうか。 channel name.UserA は、以前のチャネル dynamicChannelA をリッスンしません。

これを防ぐ方法は、サーバーからの定期的 (30 秒ごと?) ping であり、ユーザーがまだそこにいるかどうかを追跡できます。今後数か月以内に、これを自動的に行うプレゼンス API をリリースする予定です。

データベーステーブルから特定のユーザーのチャンネル名を取得する方法を使用することを考えています。チャンネルの不正な購読を防ぐ方法または方法はありますか? チャンネル名の長さに関係なく、サブスクライブキーとチャンネル名があれば、誰でもチャンネル名にサブスクライブできるからです。すべてのサブスクリプションはクライアント側で行われ、サブスクリプション キーとチャネル名が表示されるので、ただ興味があります。

主な方法は、パブリッシュ/サブスクライブ キーを戦略的に差し控えることです。適切な詳細情報を持っている人なら誰でも傍受できるというのは、あなたの言うとおりです。これは、クライアントのみのシステムの大きな問題です。当面は、それを回避するための創造的な方法を考え出す必要があります。

于 2012-06-04T18:48:17.703 に答える