Reputation: 11686
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:
ws.send('hello client');
— can I use Play's out
in the same way somehow?ws.on('message' ...
— I can use Sink.foreach()
for this, rightws.on('close' ...
— any Sink / Source 'close' event somehow?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.
Upvotes: 0
Views: 400
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