【问题标题】:Play 2.2.2-WebSocket / Equivalent of in.onClose() in Scala在 Scala 中播放 2.2.2-WebSocket / in.onClose() 的等价物
【发布时间】:2014-04-25 13:42:03
【问题描述】:

我在 Scala 中使用 Play 2.2.2。 我的控制器中有这段代码:

    def wsTest = WebSocket.using[JsValue] {
        implicit request =>
          val (out, channel) = Concurrent.broadcast[JsValue]
          val in = Iteratee.foreach[JsValue] {
            msg => println(msg)
          }
          userAuthenticatorRequest.tracked match { //detecting wheter the user is authenticated
            case Some(u) =>
              mySubscriber.start(u.id, channel)
            case _ =>
              channel push Json.toJson("{error: Sorry, you aren't authenticated yet}")
          }
          (in, out)
      }

调用此代码:

object MySubscriber {

  def start(userId: String, channel: Concurrent.Channel[JsValue]) {
    ctx.getBean(classOf[ActorSystem]).actorOf(Props(classOf[MySubscriber], Seq("comment"), channel), name = "mySubscriber") ! "start"
    //a simple refresh would involve a duplication of this actor!
  }

}

class MySubscriber(redisChannels: Seq[String], channel: Concurrent.Channel[JsValue]) extends RedisSubscriberActor(new InetSocketAddress("localhost", 6379), redisChannels, Nil) with ActorLogging {

  def onMessage(message: Message) {
    println(s"message received: $message")
    channel.push(Json.parse(message.data))
  }

  override def onPMessage(pmessage: PMessage) {
    //not used
    println(s"message received: $pmessage")
  }
}

问题在于,当用户刷新页面时,一个新的 websocket 会重新启动,涉及到名为 mySubscriber 的 Actor 的重复。

我注意到 Play 的 Java 版本有一种方法可以检测关闭的连接,以便关闭演员。 示例:

// When the socket is closed.
        in.onClose(new Callback0() {
           public void invoke() {
               // Shutdown the actor
               defaultRoom.shutdown();
           }
        });

如何用 Scala WebSocket API 处理同样的事情?每次关闭套接字时我都想关闭演员。

【问题讨论】:

  • 听起来像 Iteratee.mapmapDone 在 2.2.2 中已弃用)在 WebSockets 的情况下充当 inClose,但任何确认都会很酷:)

标签: scala websocket akka playframework-2.2


【解决方案1】:

正如@Mik378 所建议的,Iteratee.map 充当onClose 的角色。

val in = Iteratee.foreach[JsValue] {
  msg => println(msg)
} map { _ =>
  println("Connection has closed")
}

【讨论】:

  • 感谢您的确认;)
猜你喜欢
  • 2011-06-20
  • 2016-07-05
  • 2021-08-07
  • 2015-08-14
  • 1970-01-01
  • 2022-09-27
  • 2010-12-11
  • 1970-01-01
  • 2011-04-17
相关资源
最近更新 更多