1

コードで play の Enumerator (play.api.libs.iteratee.Enumerator[A]) を使用する適切な方法を探しています。「InfoBlock」タイプのオブジェクトのストリームがあり、それを websocket にリダイレクトしたいと考えています。 .私が実際に行うことは次のとおりです。

ブロックを保持するデータ構造

private lazy val buf:mutable.Queue[InfoBlock] = new mutable.SynchronizedQueue[InfoBlock]

Enumerator で使用されるコールバック

def getCallback: Future[Option[InfoBlock]] = Future{

if (!buf.isEmpty)
  Some(buf.dequeue)
else
  None}

ブロックは別のスレッドによって生成され、次を使用してキューに追加されます。

buf += new InfoBlock(...) 

次に、コントローラーで、そのデータをストリーミングするための websocket をセットアップします。

def stream = WebSocket.using[String]{ request =>

  val in = Iteratee.consume[String]()

  val enu:Enumerator[InfoBlock] = Enumerator.fromCallback1(
   isFirst => extractor.getCallback
  )

  val out:Enumerator[String] = enu &> Enumeratee.map(blk => blk.author+"  ->  "+blk.msg)

(in,out)}

それは機能しますが、大きな問題があります。接続が開いているときにブロックの束(=〜50)を送信して停止します。新しいWebSocketを開くと、別のブロックの束を取得しますが、それ以上は取得しません.いくつかのプロパティを設定しようとしましたjsオブジェクトに WebSocket 特に設定してみた

 websocket.binaryType = "arraybuffer" 

「ブロブ」の使用が原因かもしれないと思ったので、間違っていたので、問題はサーバー側にあるはずで、手がかりがありません..

4

1 に答える 1

0

Enumerator.fromCallback の Enumerator ScalaDocs から、取得関数を説明します。

入力関数。渡す入力がある場合は最終的に Some 値で償還される先物を返し、ストリームの終わりに達した場合は最終的に None で償還される先物を返します。

これは、列挙子がキューからすべてを引き出すことによって開始されることを意味します。空の場合、コールバックは None を返します。列挙子はこれをストリームの最後と見なし、closes は Done 状態を下流に送信します。それ以上のデータを探すことはありません

メッセージの受け渡しに変更可能なキューを使用するのではなく、Enumerator/Iteratee パラダイムをワーカーにプッシュしてみてください。作成しているもののインスタンスを出力する列挙子を作成し、代わりに iteratee をそこからプルさせます。必要に応じて、途中でいくつかの列挙を貼り付けて、いくつかの変換を行うことができます。

于 2013-11-14T19:24:43.700 に答える