使用 play framework 2.6 创建 websocket
Create websocket with play framework 2.6
我正在尝试使用 Play Framework 2.6 执行以下操作:
- 浏览器以服务器为目标并创建了一个 websocket
- 稍后(执行其他请求后),服务器通过先前创建的 websocket 向浏览器发送消息
1) 可以通过路线轻松完成:
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);
});
}
并且websocket可以保存在服务器端。
2) 但是我怎样才能通过 websocket 发送数据呢? (触发服务器端)
这在 2.5 中很容易做到,但文档对于播放 2.6 不是很有帮助。
谢谢
我在 Akka actors 的帮助下成功实现了 websocket。第一步定义将处理消息的 actor
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);
}
}
这个演员将根据客户创建。 ActorRef out
将向连接的客户端发送消息。在此示例中,响应将在传递给 WebSocketActor
.
的每个字符串消息上发送到客户端
现在定义 API 端点以打开客户端对 websocket 的访问。定义将在新连接上创建新的 actor 实例的 ActorFlow
public WebSocket ws() {
return WebSocket.Text.accept(request -> ActorFlow.actorRef((out) -> WebSocketActor.props(out), actorSystem, materializer));
}
根据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。这将向所有连接的客户端广播消息
actorSystem.actorSelection("/user/*/flowActor").tell("Hello", ActorRef.noSender());
不幸的是,我没有找到更改 ActorFlow 默认名称的简单方法,但也许这个答案可能对您有所帮助 play-scala-akka-websockets-change-actor-path。
您也可以从 playframework 示例中查看 play-java-websocket-example 项目。
我正在尝试使用 Play Framework 2.6 执行以下操作:
- 浏览器以服务器为目标并创建了一个 websocket
- 稍后(执行其他请求后),服务器通过先前创建的 websocket 向浏览器发送消息
1) 可以通过路线轻松完成:
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);
});
}
并且websocket可以保存在服务器端。
2) 但是我怎样才能通过 websocket 发送数据呢? (触发服务器端)
这在 2.5 中很容易做到,但文档对于播放 2.6 不是很有帮助。
谢谢
我在 Akka actors 的帮助下成功实现了 websocket。第一步定义将处理消息的 actor
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);
}
}
这个演员将根据客户创建。 ActorRef out
将向连接的客户端发送消息。在此示例中,响应将在传递给 WebSocketActor
.
现在定义 API 端点以打开客户端对 websocket 的访问。定义将在新连接上创建新的 actor 实例的 ActorFlow
public WebSocket ws() {
return WebSocket.Text.accept(request -> ActorFlow.actorRef((out) -> WebSocketActor.props(out), actorSystem, materializer));
}
根据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。这将向所有连接的客户端广播消息
actorSystem.actorSelection("/user/*/flowActor").tell("Hello", ActorRef.noSender());
不幸的是,我没有找到更改 ActorFlow 默认名称的简单方法,但也许这个答案可能对您有所帮助 play-scala-akka-websockets-change-actor-path。
您也可以从 playframework 示例中查看 play-java-websocket-example 项目。