0

我已经使用 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 socket ping 消息呢?

4

1 回答 1

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. 
    }
  }
于 2019-06-04T08:21:48.180 回答