一个 hacky 解决方案可能是让您在另一个方向(客户端到服务器)进行 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
}
}
当用户转到另一个页面,或者取消与彗星Action的连接时,它也应该取消客户端的ping计时器(如果用户更改页面,这应该是自动的,但是你必须进行一些健康检查如果您停留在同一页面等,则在彗星连接上)。当客户端停止 ping 您的操作时,计时器最终将终止套接字。
这真的很难看,因为您需要使用var
在两个操作之间共享的 a 并且它并不是真正的线程安全。它也只能支持一个客户。但是您给出的代码示例与我猜的相同。您需要跟踪哪个会话打开了哪个套接字以支持多个客户端。不过,您会失去无状态行为。
一个更干净的解决方案是使用一个小的actor系统来封装这种行为: - 你有一个 SocketActor,当它接收到 Start 消息时,它会打开一个套接字并将东西推送到 PushEnumerator 上,只要它没有,它就会一直这样做' t 收到停止消息。- 你还有一个 KeepAliveActor,它会在给定的时间后向 SocketActor 发送一个 Stop 消息,除非它之前收到过 KeepAlive 消息(所以,这里发生了什么)。
当你收到一个彗星连接时,你会产生两个新的演员(你应该有一个经理演员来隐藏这两个演员并中继消息等)并保持他们的参考链接到会话。然后,keepalive 操作将获取正确会话的 ref 并将 KeepAlive 消息发送给参与者。
SocketActor 会在收到 Stop 消息时关闭套接字并销毁链接到他的 Actor。
它涉及更多的编码,所以我不包括片段,但这将是一个简单的 AKKA 系统,所以如果你还不习惯它,你应该能够通过查看 AKKA 教程来设置它。