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:
- There's:
ws.send('hello client');— can I use Play'soutin the same way somehow? - There's:
ws.on('message' ...— I can useSink.foreach()for this, right - And
ws.on('close' ...— any Sink / Source 'close' event somehow? - And
ws.close();— how do I do that with the in out Sink Source?
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.
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 (typeIn)) and aSource(which will be used to send messages to the client (typeOut)).As you said, the sink can use some
foreachoperator 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 itscompletemethod. 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.