Based on the techinque described at this question I have written a basic microservice to provide continuously streaming ByteStrings using akka-http
. The pertinent scala code being:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Source, Flow}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.HttpEntity
import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model._
import scala.concurrent.Future
import scala.concurrent.duration._
object Server extends App {
implicit val system = ActorSystem("testServer")
implicit val materializer = ActorMaterializer()
val strToChunk =
Flow[String].map(ByteString(_))
.via(Flow[ByteString].map(HttpEntity.ChunkStreamPart(_)))
def sourceFactory =
Source(0 seconds, 1 seconds,"test").via(strToChunk)
val requestHandler: HttpRequest => HttpResponse = {
case HttpRequest(GET, Uri.Path("/stream"), _, _, _) =>
HttpResponse(entity = HttpEntity.Chunked(ContentTypes.`text/plain`,
sourceFactory))
}
val bindingFuture =
Http().bind(interface = "localhost", port = 8200).runForeach { conn =>
conn handleWithSyncHandler requestHandler
}
}
A client makes a single http request and the single response's entity is a chunked stream of ByteStrings, namely "test" every 1 second.
I verified the stream produces "test" values using a scala client. However, a very convenient debugging method would be to point a web browser at the microservice to view the Chunk stream as data comes in. I tried pointing my chrome browser to the port but the browser just hung in the loading/busy state.
So, my question is: how do I modify the HttpResponse so that a browser can display the stream in real-time?
A solution that requires a different HttpResponse entity for browser viewing than for software client consumption is fine (e.g. if the "/stream" address provides an HttpResponse for clients and the "/browserView" provides a different HttpResponse then this is an acceptable answer).