18

私は smack 3.1.0 を使用していますが、名簿を追加すると、「両方」のサブスクリプションを取得できません。誰が私を助けることができます?以下は私のコードです:

Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
Roster roster = connection.getRoster();
roster.createEntry("buddy@test.com","me",null)

コードの実行後、openfireでサブスクリプションが「to」であることを確認しました

4

5 に答える 5

42

@mschonakerの回答を書き直して、もう少し明確にします。

両方のユーザーが相互にサブスクライブし、受信したサブスクリプション要求を受け入れる必要があります。彼らをアリスとボブと呼びましょう。Alice が Bob にサブスクリプション リクエストを送信します。

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('bob@example.com');
connection.sendPacket(subscribe);

ボブはリクエストを受け取ると、それを承認します。

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('alice@example.com');
connection.sendPacket(subscribed);

Bob も Alice の存在に関心がある可能性があるため、Alice にサブスクライブします。

Presence subscribe = new Presence(Presence.Type.subscribe);
subscribe.setTo('alice@example.com');
connection.sendPacket(subscribe);

Alice は Bob のリクエストを承認する必要があります。

Presence subscribed = new Presence(Presence.Type.subscribed);
subscribed.setTo('bob@example.com');
connection.sendPacket(subscribed);

RFC6121 のセクション 3.1 は、これがどのように機能するかについての現在の最良のリファレンスです。

于 2011-05-25T22:41:32.217 に答える
10

両方のユーザーが相互にサブスクライブする必要があります。プレゼンス サブスクリプション スタンザを送信する。スマックで:

    Presence presence = new Presence(Presence.Type.subscribe);
    presence.setTo(jid);
    connection.sendPacket(presence);

RFC6121 のセクション 3.1 に意味の詳細が記載されています。

于 2011-05-24T23:44:27.047 に答える
2

わかりました、私はこれに数日間懸命に取り組み、ついに物事が機能するようになりました. @Joe Hildebrandに感謝します。あなたの答えは、これを解決するための正しい軌道に乗ってくれました。手動サブスクリプション モードで実装しました (つまり、ユーザーは別のユーザーの要求を手動で受け入れる必要があります)。

ユーザーがサブスクライブまたはサブスクライブ解除を返信していない場合、サーバーは (再ログイン時に) サブスクライブ要求をユーザーにプッシュし続けます。したがって、受信した購読リクエストをリストにローカルに保存し、それを手動で承認/拒否するための「フレンドリクエストリスト」として表示することができます。アプリケーションが再起動された場合 (したがって、サーバーに再接続した場合)、サーバーはサブスクライブ要求を再度プッシュします。

これがどのように機能するかです:

  • User1 は、サブスクライブ プレゼンスを User2 に送信します。
  • 名簿エントリは、User1 の名簿に自動的に作成されます (ただし、User2 の名簿には作成されません)。
  • User2 は User1 からサブスクライブ要求を受け取ります。
  • User2 は、サブスクライブしたプレゼンスを User2 に返信します (User2 > User1 のサブスクリプションが完了)。
  • User2 は、User1 が User2 の名簿に含まれているかどうかを確認します。User1 は User2 の名簿にありません。User2 は、サブスクライブ プレゼンスを User1 に送り返します。
  • 名簿エントリは、User2 の名簿に自動的に作成されます。
  • User1 は、User2 からサブスクライブ プレゼンスを受け取ります。
  • User1 は、User2 が User1 の名簿に含まれているかどうかを確認します。User2 は User1 の名簿に含まれています。User1 は、サブスクライブしたプレゼンスを User2 に返信します (User2 > User1 のサブスクリプションが完了)。

            final Presence newPresence = (Presence) packet;
            final Presence.Type presenceType = newPresence.getType();
            final String fromId = newPresence.getFrom();
            final RosterEntry newEntry = getRoster().getEntry(fromId);
    
            if (presenceType == Presence.Type.subscribe)
            {
                //from new user
                if (newEntry == null)
                {
                    //save request locally for later accept/reject
                    //later accept will send back a subscribe & subscribed presence to user with fromId
                    //or accept immediately by sending back subscribe and unsubscribed right now
                }
                //from a user that previously accepted your request
                else
                {
                    //send back subscribed presence to user with fromId
                }
            }
    
于 2014-01-29T10:07:45.037 に答える
1

直火サーバーを使用している場合は 、両方のサブスクリプションで名簿を作成するユーザー サービス プラグインを使用することもできます...

于 2014-03-12T13:13:27.220 に答える