【问题标题】:Implementing long polling in scala and play 2.0 with akka在scala中实现长轮询并用akka玩2.0
【发布时间】:2012-04-22 20:27:02
【问题描述】:
【问题讨论】:
标签:
scala
playframework
playframework-2.0
akka
long-polling
【解决方案2】:
我不确定您正在寻找什么,但彗星时钟示例中有一个非常简单的解决方案,您可以适应使用 AKKA 演员。它使用无限 iframe 而不是长轮询。我已经为更复杂的应用程序使用了一个改编版本,在 AKKA 演员中执行多个数据库调用和长时间计算,它工作正常。
def enum = Action {
//get your actor
val myActorRef = Akka.system.actorOf(Props[TestActor])
//do some query to your DB here. Promise.timeout is to simulate a blocking call
def getDatabaseItem(id: Int): Promise[String] = { Promise.timeout("test", 10 milliseconds) }
//test iterator, you will want something smarter here
val items1 = 1 to 10 toIterator
// this is a very simple enumerator that takes ints from an existing iterator (for an http request parameters for instance) and do some computations
def myEnum(it: Iterator[Int]): Enumerator[String] = Enumerator.fromCallback[String] { () =>
if (!items1.hasNext)
Promise.pure[Option[String]](None) //we are done with our computations
else {
// get the next int, query the database and compose the promise with a further query to the AKKA actor
getDatabaseItem(items1.next).flatMap { dbValue =>
implicit val timeout = new Timeout(10 milliseconds)
val future = (myActorRef ? dbValue) mapTo manifest[String]
// here we convert the AKKA actor to the right Promise[Option] output
future.map(v => Some(v)).asPromise
}
}
}
// finally we stream the result to the infinite iframe.
// console.log is the javascript callback, you will want something more interesting.
Ok.stream(myEnum(items1) &> Comet(callback = "console.log"))
}
请注意,这个 fromCallback 不允许您将枚举数与“andThen”组合,在 play2 的主干版本中有一个 generateM 方法,如果您想使用组合可能更合适。
这不是长轮询,但它工作正常。