我不确定是否遇到默认超时(我可以在某个地方设置吗?),但是也许我错过了一些东西。当客户端的浏览器建立websocket连接时,我会保持持久性。然后,在断开连接时,我删除了该持久对象。很简单。断开连接通常在客户端关闭浏览器时触发,但是不会在客户端关闭其wi-fi连接时触发(在MacBook Pro上进行测试,这无关紧要)。

在Scala Controller 中,我记录了每个in消息,但是wit-fi关闭时,没有任何出现(从docs中,我希望有EOF吗?)。

我认为这一定是一个错误,正如我从解释服务器WS protocol 的方式中获取的那样,必须关闭WebSocket
连接,并应记录问题。
但是后者不会发生。

val in = Iteratee.foreach[String](x => {
  logger.info("Websocket msg: " + x)
   // expect EOF?
   x match {
     case "persist" => // persist some object
   }
}).mapDone { x =>
   // delete my persisted object (never happens unless browser/tab closed)
}

有人经历过吗?我已经尝试了一个简单的 Controller 和与我的配置匹配的东西。下面的ws3ws2 Controller 都不起作用。玩!下面的代码:
object Application extends Controller {

  private def ws(out: PushEnumerator[String]) = {

    Logger.logger.info("ws()")

    val in = Iteratee.foreach[String](x => {
      Logger.logger.info("Websocket msg: " + x)
      try {
        x match {
          case "persist" => Logger.logger.info("PERSIST")
        }
      } catch {
        case e: Exception => {
          Logger.logger.info("NOT RECOGNIZED COMMAND, NO PERSIST")
        }
      }
    }).mapDone { x =>
      Logger.logger.info("STOP PERSIST")
    }
    in
  }

  def ws2() = WebSocket.using[String] { request =>

    Logger.logger.info("ws2()")

    val out = Enumerator.imperative[String]()
    val in = ws(out)

    (in, out)
  }

  def ws3() = WebSocket.using[String] { request =>

    Logger.logger.info("ws3()")

    val out = Enumerator.imperative[String]()
    val in = Iteratee.foreach[String](x => {
      Logger.logger.info("Websocket msg: " + x)
      try {
        x match {
          case "persist" => Logger.logger.info("PERSIST")
        }
      } catch {
        case e: Exception => {
          Logger.logger.info("NOT RECOGNIZED COMMAND, NO PERSIST")
        }
      }
    }).mapDone { x =>
      Logger.logger.info("STOP PERSIST")
    }
    (in, out)
  }

  def view() = Action { implicit request =>
    Ok(views.html.index.render(""))
  }
}

该 View 很简单:
@(message: String) @main("Welcome to Play 2.0") {

@play20.welcome(message) }

<script type="text/javascript" charset="utf-8">
    var sock = new WebSocket("ws://192.168.1.120:9001/ws3");

    sock.onopen = function(event) {
        sock.send('persist');
    }
</script>

路线:
GET     /ws2                          controllers.Application.ws2
GET     /ws3                          controllers.Application.ws3
GET     /view                         controllers.Application.view

最佳答案

这不是特定于Play框架,而是与网络相关的问题。如果正常断开连接,则另一端会发送FIN数据包,而服务器知道它已挂断。如果另一端没有网络连接,则不能建立网络连接。

如何确定 socket 是否打开呢?尝试读取或写入时,您将获得异常。但是对于非阻塞模型,它本身不会发生。因此,在您的情况下,我将:

  • 超时
  • 使JavaScript在超时时间内发送ping
  • 如果没有ping到,请断开
  • 的连接

    或从服务器端发送ping(写入套接字)。

    关于scala - Websocket 'hard'断开不明显吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12681565/

    10-12 01:12