Как отправить сообщение веб-сокета с сервера клиенту через определенные промежутки времени? - PullRequest
0 голосов
/ 04 июня 2019

Я реализовал сервер веб-сокетов, используя Play Framework. Сервер может принимать соединения и отвечать клиентам. Если соединения простаивают в течение некоторого времени, сервер автоматически закрывает соединение. Я не уверен, есть ли какая-либо конфигурация, чтобы сделать соединения всегда живыми. Таким образом, чтобы отслеживать состояние соединения (соединение активно или нет), сервер должен отправить клиенту сообщение 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"
    }
}

Итак, как отправить пинг-сообщение веб-сокета с сервера клиенту через определенные промежутки времени?

1 Ответ

0 голосов
/ 04 июня 2019

Вы можете использовать планировщик для отправки сообщения клиенту через определенный интервал.Ниже приведен один из примеров, который можно использовать для реализации вашего сценария:

  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. 
    }
  }
...