[英]Play Framework Persistent WebSocket Connection
在当前版本的 Play Framework 中,无法使 WebSocket 连接持久化。
https://www.playframework.com/documentation/2.8.x/ScalaWebSockets#Keeping-a-WebSocket-Alive
我有下面的一段代码,需要这个 WebSocket 连接是持久的。
class ProvisioningActor(sink: ActorRef) extends Actor {
private[this] val source = Observable.interval(appConfig.pingInterval).map(elem => elem.toInt)
private[this] val ping = Consumer.foreach[Int](x => self ! x)
private[this] val task = source.consumeWith(ping).runToFuture
override def receive: Receive = {
case jsValue: JsValue =>
logger.debug(s"Received OCPPCallRequest: \n ${Json.prettyPrint(jsValue)}")
jsValue.validate[OCPPCallRequest].asEither match {
case Right(ocppCall) => handleOCPPCallRequest(ocppCall).materialize.map {
case Failure(fail) => sink ! JsError(s"${fail.getMessage}")
case Success(succ) => sink ! Json.toJson(succ)
}
case Left(errors) =>
logger.error(s"Errors occurred when validating OCPPCallRequest: \n $errors")
sink ! Json.toJson(s"error -> ${errors.head._2}") // TODO: Work on this issue here on how we want to propagate errors
}
case x: Int =>
logger.debug(s"Elem: $x")
handleHeartBeatRequest(2, "HeartbeatRequest").materialize.map {
case Failure(fail) => sink ! JsError(s"${fail.getMessage}")
case Success(succ) => sink ! Json.toJson(succ)
}
case msg: Any =>
logger.warn(s"Received unknown message ${msg.getClass.getTypeName} that cannot be handled, " +
s"eagerly closing websocket connection")
task.cancel()
self ! PoisonPill
}
}
它有点像将心跳消息发送回客户端。 我的问题是:
还有其他建议吗?
我们将 PlayFramework websockets 用于长时间运行的会话,繁忙的服务器支持超过 1000 个并发 Websocket 连接,并且缺少乒乓数据包会导致空闲的 websocket 连接被中间防火墙、代理等以及播放框架 idleTimeout 本身终止 - play.server.https.idleTimeout.
从 PlayFramework v2.1(现在使用 v2.8)开始,我们一直在使用 Sockjs 协议,Play Sockjs - https://github.com/fdimuccio/play2-sockjs ,它使用应用层心跳https://github.com/fdimuccio /play2-sockjs/wiki/API-reference-for-0.5.x#configuring-sockjs-handler
package controllers
import scala.concurrent.duration._
import play.api.mvc._
import play.sockjs.api._
// mixin SockJSRouter trait with your controller
class SockJSController extends Controller with SockJSRouter {
// override this method to specify custom SockJSSettings
override protected val settings = SockJSSettings(websocket = false, heartbeat = 55 seconds)
// here goes the request handler
def sockjs = SockJS.accept[String, String] { request =>
...
}
}
我们在生产中使用 20s 心跳,这已被证明非常安全,每个连接都有相同的心跳设置,这对我们的用例很有效。
本主题可能有帮助: Play2.5 Java WebSockets
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.