私はplay-iteratees-extrasはあなたを助けなければならないと思います。このライブラリは、Enumerator/IterateeパターンでJsonを解析することを可能にし、もちろん、すべてのデータを受け取るのを待っていません。
たとえば、「無限」のJson配列を表す、無限のバイトストリームを作成しないようにします。
import play.api.libs.iteratee.{Enumeratee, Enumerator, Iteratee}
var i = 0
var isFirstWas = false
val max = 10000
val stream = Enumerator("[".getBytes) andThen Enumerator.generateM {
Future {
i += 1
if (i < max) {
val json = Json.stringify(Json.obj(
"prop" -> Random.nextBoolean(),
"prop2" -> Random.nextBoolean(),
"prop3" -> Random.nextInt(),
"prop4" -> Random.alphanumeric.take(5).mkString("")
))
val string = if (isFirstWas) {
"," + json
} else {
isFirstWas = true
json
}
Some(Codec.utf_8.encode(string))
} else if (i == max) Some("]".getBytes) // <------ this is the last jsArray closing tag
else None
}
}
いいえ、この値には10000(以上)のオブジェクトのjsArrayが含まれています。配列内の各オブジェクトのデータを含むケースクラスを定義します。
case class Props(prop: Boolean, prop2: Boolean, prop3: Int, prop4: String)
今、各項目
import play.extras.iteratees._
import JsonBodyParser._
import JsonIteratees._
import JsonEnumeratees._
val parser = jsArray(jsValues(jsSimpleObject)) ><> Enumeratee.map { json =>
for {
prop <- json.\("prop").asOpt[Boolean]
prop2 <- json.\("prop2").asOpt[Boolean]
prop3 <- json.\("prop3").asOpt[Int]
prop4 <- json.\("prop4").asOpt[String]
} yield Props(prop, prop2, prop3, prop4)
}
をしてください解析されること、パーサを書き、jsArray
、jsValues
とjsSimpleObject
ためdocを参照してください。パッケージはCharString
としてバイトをデコードします
val result = stream &> Encoding.decode() ><> parser
Encoding.decode()
JsonIterateesから:結果のプロデューサーを構築します。 result
の値にはEnumerator[Option[Item]]
の型があり、この列挙子にはiterateeを適用して解析処理を開始できます。
合計で、どのようにバイトを受け取るのかわかりません(解決策はこれに大きく依存します)が、問題の解決策の1つを表示すると思います。
明確にするために、このJSONストリームを受け取ったり、このストリームをブロードキャストしようとしていますか?ブロードキャストの場合、内部表現(イテレータ、スカラストリームなど)は何ですか?また、コミュニケーションは配列でなければならないのですか、それとも個々のドメインオブジェクトのストリームである可能性がありますか? –
@RamonJRomeroyVigilこのストリームは完全に外部になります。 – Martijn
あなたの特別なケースでは、 '}'を閉じるのを待つことができ、その間にテキスト用にあなたが選んだデシリアライザを呼び出すことができます。これにはいくつかの操作が必要で、おそらくByteStringのバッファリングが必要ですが、かなり基本的です。 –