I am trying to do the following with Play Framework 2.6:
Point 1 can be easily done with a route:
public WebSocket socket() {
return WebSocket.Text.accept(request -> {
// Log events to the console
Sink<String, ?> in = Sink.foreach(System.out::println);
// Send a single 'Hello!' message and then leave the socket open
Source<String, ?> out = Source.single("Hello!").concat(Source.maybe());
return Flow.fromSinkAndSource(in, out);
});
}
and the WebSocket can be saved server side.
This was easy to do with 2.5 but the documentation is not very helpful for Play 2.6.
I've managed to implement websocket with help of Akka actors. At first step define actor that will handle messages
public class WebSocketActor extends AbstractActor {
private final ActorRef out;
@Inject
public WebSocketActor(ActorRef out) {
this.out = out;
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(String.class, message ->
out.tell("Sending message at " + LocalDateTime.now().toString(), self())
)
.build();
}
public static Props props(final ActorRef out) {
return Props.create(WebSocketActor.class, out);
}
}
This actor will be created per client. ActorRef out
will send message to connected client. In this example response is send to client on each string message passed to WebSocketActor
.
Now define API endpoint to open access to websocket for clients. Define ActorFlow that will create new instance of actor on new connection
public WebSocket ws() {
return WebSocket.Text.accept(request -> ActorFlow.actorRef((out) -> WebSocketActor.props(out), actorSystem, materializer));
}
According to source code ActorFlow creates actors with flowActor
name. So to send message to websockets somewhere in the code we can find actors by their path. This will broadcast message to all connected clients
actorSystem.actorSelection("/user/*/flowActor").tell("Hello", ActorRef.noSender());
Unfortunately I didn't find easy way to change ActorFlow default name but maybe this answer may help you play-scala-akka-websockets-change-actor-path.
Also you can check play-java-websocket-example project from playframework examples.