Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Receiving Server-Sent-Events

Set-up:

A project I am working on has a pub/sub server with an HTTP interface. Subscription works by accepting server-sent-events.

curl -X GET server:port/topics/news

which will be pushed whenever a message is published to the given topic URL

curl -X PUT server:port/topics/news -d "Politician Lies!"

Problem:

I have a scala project which needs to subscribe to this pub/sub server. The Play! framework is able to handle this by using PlayWS with Enumeratee + Iteratee. Unfortunately, the PlayWS library requires that a Play! Application is in scope and I am not using Play. Is there a library (with minimal dependancies) I can use which allows me to accept server-sent-events? I'll need at least one working example in order to get started.

I have a preference for scala libraries but I'm willing to accept a Java solution if I have to.

like image 687
Jake Greene Avatar asked May 16 '14 19:05

Jake Greene


2 Answers

I've accepted Manuel Bernhardt's answer because it led me in the right direction but I feel a full example is important for anyone else with this issue.

I updated my build.sbt file to include PlayWS 2.3 and the Iteratees library.

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-ws" % "2.3.0",
  "com.typesafe.play" %% "play-iteratees" % "2.3.0"
)

The WS singleton requires an implicit Play Application to be used (something I don't have or want) so instead I will need to create my own client

val builder = new (com.ning.http.client.AsyncHttpClientConfig.Builder)()
val client = new play.api.libs.ws.ning.NingWSClient(builder.build())

I then create my Iteratee so that I can handle my server-sent-events.

def print = Iteratee.foreach { chunk: Array[Byte] => 
  println(new String(chunk))
}

and finally subscribe to the server

client.url("http://localhost:8080/topics/news").get(_ => print)

Now, when an event is sent

curl -X PUT server:port/topics/news -d "Politician Lies!"

My Scala application will print the received event

data: Politician Lies!
like image 180
Jake Greene Avatar answered Sep 22 '22 18:09

Jake Greene


You have several possibilities:

In Play 2.3, the WS library is now a separate library, so that should help. RC2 is already available

Alternatively, you could depend on Play 2.x and use a StaticApplication like so:

val application = new StaticApplication(new java.io.File("."))

This will essentially bootstrap a Play application, and from there on you can use the WS library as usual

like image 34
Manuel Bernhardt Avatar answered Sep 20 '22 18:09

Manuel Bernhardt