13

分散環境の可能性があるPlay2.0でロングポーリングを実装しています。私が理解しているのは、Playがリクエストを受け取ると、更新の保留中の通知を一時停止してから、データベースに移動して新しいデータをフェッチして繰り返す必要があるということです。Play 2.0が提供するチャットの例を見始めましたが、それはWebSocketにあります。さらに、配布できるようには見えません。なので、アッカのイベントバスを利用しようと思いました。私はイベントストリームの実装を採用し、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ブラウザーで「死のスピナー」を引き起こしたため、満足のいくものではありませんでした(つまり、常にロードされていることを示しています)

とにかく、良い例を見つけることができませんでしたが、promiseを使用して独自の概念実証を作成することができました: https ://github.com/kallebertell/longpoll

于 2012-11-13T20:11:53.007 に答える