HTTPセッションとCometDセッションのライフサイクルは異なります。たとえば、一時的な接続障害が発生した場合、CometDセッションは失敗し、サーバーはクライアントに再ハンドシェイクを要求するため、別のCometDセッションが作成されます(同じユーザーですが、CometDが異なりますclientId)。同じ場合、はHttpSession同じままになります。
HttpSessionこれを念頭に置いて、ユーザー名、コレスポンデント、およびコレスポンデントの間のマッピングをアプリケーションレベルで維持する必要がありますServerSession。このマッピングを呼びましょうHttpCometDMapper。新しいユーザーがログインするたびに、その名前(またはユーザーの別の一意の識別子)、、、HttpSessionおよび現在のを登録しServerSessionます。HttpSessionおそらく、最初にユーザー名とをリンクし、次に同じユーザー名を。とリンクする2段階のプロセスが必要になりますServerSession。
CometDの再ハンドシェイクが実行された場合は、マッパーを新しいで更新しますServerSession。
HttpSessionListenerを登録することで2つのセッションをリンクできます。これにより、破壊されたときに、マッパーからHttpSession現在のCometDを取得して呼び出すことができます。ServerSessionServerSession.disconnect()
CometDには、持っているような非アクティブタイムアウトの概念がないため、その逆は少し注意が必要HttpSessionです。独自のロジックを使用してアプリケーションに実装する必要があります。
それを行うことの一部は、次のようRemoveListenerににを登録することです。ServerSession
serverSession.addListener(new ServerSession.RemoveListener()
{
public void removed(ServerSession session, boolean timeout);
{
if (!timeout)
{
// Explicitly disconnected, invalidate the HttpSession
httpCometDMapper.invalidate(session);
}
}
});
このリスナーは、クライアント(およびサーバー-再入可能性に注意)からの明示的な切断を監視します。
少し難しいのは、非明示的な切断に同じメカニズムを実装することです。この場合、timeoutパラメーターはtrueになりますが、一時的なネットワーク障害が原因で発生した可能性があり(クライアントが完全に消えるのではなく)、同じユーザーが既に新しいを使用して再ハンドシェイクしている可能性がありますServerSession。
この場合、アプリケーションのタイムアウトで問題を解決できると思います。タイムアウトがServerSession原因で削除されたことが表示されたら、そのユーザーに注意してアプリケーションのタイムアウトを開始します。同じユーザーが再ハンドシェイクする場合は、アプリケーションのタイムアウトをキャンセルします。そうしないと、ユーザーが実際にいなくなり、アプリケーションのタイムアウトが期限切れになり、ユーザーも無効になりHttpSessionます。
上記は単なるアイデアと提案です。実際の実装は、アプリケーションの詳細に大きく依存します(そのため、CometDはそのままでは提供されません)。
重要なポイントは、マッパー、HttpSessionListenerおよびRemoveListener、およびこれらのコンポーネントのライフサイクルを知ることです。それを管理したら、アプリケーションに適切なことを行う適切なコードを記述できます。
最後に、CometDにはHttpSession、インスタンスを介してトランスポートに依存しない方法で対話する方法があることに注意してください。BayeuxContextこれは、から取得できますBayeuxServer.getContext()。特に、に格納されているトークンを取得する場合に、それが物事を単純化できるかどうかを確認するためにも、それを確認することをお勧めしますHttpSession。