2012-04-10 9 views
13

私は、潜在的に分散環境でPlay 2.0で長いポーリングを実装しています。私が理解していることは、Playが要求を受け取ると、更新の保留中の通知を中断し、次にdbに行き新しいデータをフェッチして繰り返すことです。 Play 2.0が提供するチャットの例を見てみましたが、websocketにあります。さらに、配布可能なようには見えません。だから私はAkkaのイベントバスを使うつもりだと思った。私はイベントストリームの実装を取り、LookupClassificationで自分自身を複製しました。しかし、私はどのように私はメッセージを取得するつもりですか(またはその問題については、ActorRefではなくサブスクライバーになるべきですか?)スカラーで長いポーリングを実装し、akkaで2.0を再生

EventStreamの実装: https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/event/EventStream.scala

答えて

5

私はそれはあなたが探しているものであることを確認していない、しかし、あなたがアッカの俳優を使用するように適応させることができ彗星・クロックのサンプルでは非常に簡単な解決策は、そこにあります。長いポーリングの代わりに無限のiframeを使用します。私は、より複雑なアプリケーションのために適応されたバージョンを使用して、複数のDB呼び出しと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はあなたが組み合わせを使用する場合は、より適切な場合がありますgenerateM方法がPLAY2のトランクバージョンであり、あなたは「andThen」と列挙子を組み合わせることができないことに注意してください。

長いポーリングはありませんが、正常に動作します。

1

同じことを探しているうちにあなたの質問に遭遇しました。

彼らはWebKitのブラウザで「死のスピナー」を引き起こしたとして、私はストリーミングソリューションは、あっけなく見つかった(つまり、それはすべての時間をロードしていることを示す)

とにかく、良い例を見つけるのいずれかの運を持っているが、私はに管理されていませんでした約束を使って私自身の概念実証を作成してください: https://github.com/kallebertell/longpoll

関連する問題