ハッキーな解決策は、反対方向 (クライアントからサーバー) に ping を呼び出すことです。
10 秒以内に接続がキャンセルされなかった場合に接続を破棄するタイマーを設定します (いつでもより長い期間を設定できます)。
var timer;
def comet = Action {
timer = Akka.system.scheduler.scheduleOnce(10 seconds) {
socketClient.disconnect
}
...
}
ping を受信するアクションをセットアップし、javascript コードでタイマーをセットアップして、9 秒ごとにそのルートにリクエストを送信します。
def keepAlive = Action {
cancel.cancel
timer = Akka.system.scheduler.scheduleOnce(10 seconds) {
socketClient.disconnect
}
}
ユーザーが別のページに移動するか、comet アクションへの接続をキャンセルすると、クライアント側の ping タイマーもキャンセルする必要があります (ユーザーがページを変更した場合、これは自動的に行われるはずですが、ヘルスチェックが必要になります)同じページにとどまる場合はコメット接続で、など)。クライアントがアクションへの ping を停止すると、タイマーは最終的にソケットを強制終了します。
var
2 つのアクション間で共有されるa を使用する必要があり、実際にはスレッドセーフではないため、これは非常に醜いです。また、サポートできるクライアントは 1 つだけです。しかし、あなたが与えたコード例は私が推測するものと同じです。複数のクライアントをサポートするには、どのセッションがどのソケットを開いているかを追跡する必要があります。ただし、ステートレスな動作は失われます。
よりクリーンな解決策は、小さなアクター システムを使用してこの動作をカプセル化することです。 t Stop メッセージを受け取ります。- また、KeepAlive メッセージを以前に受信していない限り、一定時間後に SocketActor に Stop メッセージを送信する KeepAliveActor もあります (つまり、ここで何が起こっているのか)。
コメット接続を受信すると、2 つの新しいアクターをスポーンし (2 つのアクターを非表示にしてメッセージを中継するためのマネージャー アクターが必要です)、それらへの参照をセッションにリンクしたままにします。キープアライブ アクションは、適切なセッションの参照をフェッチし、キープアライブ メッセージをアクターに送信します。
SocketActor は、Stop メッセージを受信すると、ソケットを閉じて、リンクされているアクターを破棄します。
もう少し複雑なコーディングなので、スニペットは含めませんが、単純な AKKA システムになるので、まだ慣れていない場合は、AKKA チュートリアルをチェックしてセットアップできるはずです。