【发布时间】: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.map(mapDone在 2.2.2 中已弃用)在 WebSockets 的情况下充当 inClose,但任何确认都会很酷:)
标签: scala websocket akka playframework-2.2