KajMagnus
KajMagnus

Reputation: 11686

How use Play Framework 2.8 WebSocket with Sink and Source?

I think I'd like to use Play's and Akka's in: Sink and out: Source for WebSocket (rather than creating an actor). I'm so far unable to figure out how to do that though.

How do I send messages to an 'out' Source? How do I close the 'in' and 'out'? How do I know if the client closed the connection?

I looked at the Nodejs WebSocket docs: https://github.com/websockets/ws#echowebsocketorg-demo:

Or should I use something else than an in: Sink and out: Source? I'd rather not create an actor (or, I have questions about that too — that'd be a different topic).

***

Here's the example in Play's documentation:

// Log events to the console
val in = akka.stream.scaladsl.Sink.foreach[String](println)

// Send a single 'Hello!' message and then leave the socket open
val out = akka.stream.scaladsl.Source.single("Hello!")
  .concat(akka.stream.scaladsl.Source.maybe)

But this leaves me wondering how to close the 'in' Sink and 'out' Source (some time later, not immediately)
and how do I know when the client closes them. And how to send useful messages to 'out': looking at the Source docs, I don't find anything I can use to send different messages later on, to the 'out'. Maybe the ask method? "Use the ask pattern to send a request-reply message to the target ref actor" — unclear to me what that means.

Upvotes: 0

Views: 400

Answers (1)

Antoine
Antoine

Reputation: 133

The idea in this case is to use a Flow "fromSinkAndSource" (https://doc.akka.io/docs/akka/current/stream/operators/Flow/fromSinkAndSource.html), which will require you to give a Sink (which will consume messages coming from the client (type In)) and a Source (which will be used to send messages to the client (type Out)).

As you said, the sink can use some foreach operator as you said (there might be better options but for now I guess it's ok).

For the source, I would suggest you to use a Source.queue (https://doc.akka.io/docs/akka/current/stream/operators/Source/queue.html). Once you have a queue, you can terminate it by calling its complete method. Note, however, that you will need to keep track of the reference to the source somewhere, with a reference to what client it is involved with.

I hope that helps.

Upvotes: 1

Related Questions