【问题标题】:Implementing long polling in scala and play 2.0 with akka在scala中实现长轮询并用akka玩2.0
【发布时间】:2012-04-22 20:27:02
【问题描述】:

我在潜在的分布式环境中在 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

【问题讨论】:

    标签: scala playframework playframework-2.0 akka long-polling


    【解决方案1】:

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

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

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

    【讨论】:

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

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

      【讨论】:

        猜你喜欢
        • 2022-01-14
        • 2013-02-17
        • 2012-09-15
        • 1970-01-01
        • 2012-06-10
        • 2012-04-01
        • 2011-09-16
        • 2012-06-02
        • 2011-10-14
        相关资源
        最近更新 更多