13

我在潜在的分布式环境中在 Play 2.0 中实现长轮询。我理解的方式是,当 Play 收到请求时,它应该暂停挂起的更新通知,然后去数据库获取新数据并重复。我开始查看 Play 2.0 提供的聊天示例,但它位于 websocket 中。此外,它看起来无法分发。所以我想我会使用 Akka 的事件总线。我采用了 eventstream 实现并使用 LookupClassification 复制了我自己的实现。但是,我对如何返回消息感到困惑(或者就此而言,订阅者应该是什么而不是 ActorRef)?

EventStream 实现: https ://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/event/EventStream.scala

4

2 回答 2

5

我不确定这是否是您正在寻找的,但彗星时钟样本中有一个非常简单的解决方案,您可以适应使用 AKKA 演员。它使用无限 iframe 而不是长轮询。我已经为更复杂的应用程序使用了一个改编版本,在 AKKA 演员中执行多个 DB 调用和长时间计算,它工作正常。

  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 方法,如果您想使用组合可能更合适。

这不是长轮询,但它工作正常。

于 2012-05-25T14:04:11.620 回答
1

我在寻找同样的东西时偶然发现了你的问题。

我发现流媒体解​​决方案不令人满意,因为它们在 webkit 浏览器中导致“死亡旋转器”(即显示它一直在加载)

无论如何,没有任何运气找到好的例子,但我设法使用承诺创建了自己的概念证明: https ://github.com/kallebertell/longpoll

于 2012-11-13T20:11:53.007 回答