我已经使用Play Framework实现了Web套接字服务器。服务器可以建立连接并响应客户端。 如果连接空闲了一段时间,则服务器会自动关闭连接。 我不确定是否有任何配置可以使连接始终保持活动状态。 因此,为了监视连接状态(连接是否存在),服务器需要在特定时间向客户端发送PING消息 间隔,它应该从客户端收到PONG。
下面是我的服务器实现
@Singleton
class RequestController @Inject()(cc: ControllerComponents)(implicit system: ActorSystem, mat: Materializer) extends AbstractController(cc) {
def ws = WebSocket.accept[String, String] {req =>
ActorFlow.actorRef { out =>
ParentActor.props(out)
}
}
}
object ParentActor {
def props(out: ActorRef) = Props(new ParentActor(out))
}
class ParentActor(out : ActorRef) extends Actor {
override def receive: Receive = {
case msg: String => out ! s"Echo from server $msg"
}
}
那么如何在特定时间间隔从服务器向客户端发送Web套接字ping消息?
答案 0 :(得分:0)
您可以使用调度程序,以便在一定间隔内将消息发送到客户端。以下是可用于实现方案的示例之一:
class ParentActor(out : ActorRef) extends Actor {
var isPongReceived = false
override def receive: Receive = {
case "START" =>
// Client started the connection, i.e. so, initially let mark client pong receive status as true.
isPongReceived = true
out ! s"Echo from server - Connection Started"
// This part schedules a scheduler that check in every 10 seconds if client is active/connected or not.
// Sends PING response if connected to client, otherwise terminate the actor.
context.system.scheduler.schedule(new DurationInt(10).seconds,
new DurationInt(10).seconds) {
if(isPongReceived) {
// Below ensures that server is waiting for client's PONG message in order to keep connection.
// That means, next time when this scheduler run after 10 seconds, if PONG is not received from client, the
// connection will be terminated.
isPongReceived = false
out ! "PING_RESPONSE"
}
else {
// Pong is not received from client / client is idle, terminate the connection.
out ! PoisonPill // Or directly terminate - context.stop(out)
}
}
case "PONG" => isPongReceived = true // Client sends PONG request, isPongReceived status is marked as true.
}
}