0

~50 ユーザーのアプリケーションを作成しました。チャネル API を使用しようとしていますが、メッセージ送信のテスト中に問題が発生しました。トークンをデータベースに保存しているので、ユーザーが同じインターフェイスで複数のタブを開いた場合に同じトークンを使用でき、有効期限が切れたときにトークンをリセットするサーブレットがあります。

アプリケーションを再デプロイするか、アプリのバージョンを変更するまで、問題なく動作します。メッセージの受信を停止します。古いアプリ バージョンのトークンを使用してチャネルを開こうとすると、エラーなどはスローされず、チャネルは開きますが、そのチャネルでメッセージを受信しません。
トークンをリセットすると、再び正常に動作します。

このバグの解決策を知っている人はいますか? 人々が働いている間に頻繁に展開するので、無視することはできません。

私の最善の推測はChannelServiceFactory.getChannelService()、別のインスタンスを返すChannelServiceので、呼び出すchannelService.sendMessage("id","message");と別のチャネルに送信されるということです。

4

1 に答える 1

1

保存されたトークンがアプリの再デプロイで機能しない理由は説明できませんが (動作するはずです)、バージョンを変更すると機能しない理由は説明できます。簡単に言うと、トークンはアプリのバージョンに固有です。

まず、この理由: 異なるデータを送信したり、メッセージ形式を変更したり、異なるバージョンで何かを変更したりするアプリケーションが、バージョンの境界を越えてメッセージを送信しないようにする必要があります。v1 の JavaScript バンドルを v2 のサーブレットに対してレンダリングしたくないのと同じように、v1 の JavaScript メッセージ ハンドラーが v2 サーブレットからメッセージを受信する (またはその逆) ことは望ましくありません。

したがって、うまくいけば何が起こっているのかを明確にするために:

チャネルは、appid、アプリのバージョン、および createChannel または sendMessage を呼び出すときに指定する clientid の組み合わせによって識別されます。Channel API の実装では、appid/clientid -> token のマッピングは保存されません。大幅に単純化するために、createChannel を次のように考えることができます。

public String createChannel(clientid) {
  // obviously we don't really just append strings to each other for actual implementation.
  return encryptStringSomehow(clientid + globalAppInfo.version + globalAppInfo.appid);
}

sendMessage は次のようになります。

public void sendMessage(clientid, message) {
  // identify the JID used for this channel.
  JID xmppJid = new JID(mutateString(clientid + globalAppInfo.version + globalAppInfo.appid),
                        CHANNEL_XMPP_DOMAIN); // some domain used for channel messages
  // send the <message> stanza to that jid with the application message as the body
  xmppService.sendMessage(xmppJid, encodeSomehow(message));
}

クライアント側では、チャネルを担当するサーブレットがトークンを復号化し、sendMessage関数と同じ方法で作成された JID によって識別されるエンドポイントにバインドします。

つまり、トークンは、トークンを作成した同じバージョンのアプリから送信されたメッセージに対してのみ有効です。

于 2011-12-20T17:21:39.360 に答える