AsyncContext を使用して、メッセージを非同期的にクライアントに送り返すことができるサーベットを実装しています。他のサーブレットは、クライアントのメッセージをキューに入れることができる必要があります。これは、ブラウザが AJAX を介してメッセージを要求したときにクライアントに提供されます。
私の現在の実装では、静的タイマーを使用しています。
private static Timer messageSender = new Timer("MessageSerlvetSender", true);
これはデーモン スレッドとして作成されるため、サーブレット コンテナーのスレッドが必要以上に長く存続することはありません。他のサーブレットは、次の方法でメッセージをキューに入れます。
public static void write(HttpServletRequest req, MessageType type, String message) {
try {
synchronized (messageSender) {
messageSender.schedule(new MessageTask(hashSession(req), type, message), MSG_DELAY_MS, MSG_TIMEOUT_MS);
}
} catch (IllegalStateException ex) {
// Timer daemon thread has been canceled
messageSender = new Timer("MessageSerlvetSender", true);
write(req, type, message);
}
}
MessageTask
(セッション ID を使用して) ハッシュ マップに追加された を取得しAsyncContext
、メッセージを書き込み、コンテキストを完了し、成功時にタスクをキャンセルする実行可能ファイルです。
これはスレッドセーフであり、デーモン スレッドが終了した場合にタイマーを再起動できます。この実装は、サーブレットの API に準拠するために状態を想定しないようにしていますが、それは...汚い感じがします。この状況でのベストプラクティスは何ですか? HTTP セッション属性を利用するにはどうすればよいですか?