使用play framework 2.6创建websocket

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (248)

我正在尝试使用Play Framework 2.6执行以下操作:

  1. 浏览器以服务器为目标,并创建websocket
  2. 稍后(在执行其他一些请求之后),服务器通过先前创建的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没什么帮助。

谢谢

提问于
用户回答回答于

我已经设法实现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);
    }
}

将根据客户端创建此actor。ActorRef out将向已连接的客户端发送消息。在此示例中,响应将在传递给的每个字符串消息上发送给客户端WebSocketActor

现在定义API端点以打开对客户端websocket的访问。定义将在新连接上创建actor的新实例的ActorFlow

public WebSocket ws() {
    return WebSocket.Text.accept(request -> ActorFlow.actorRef((out) -> WebSocketActor.props(out), actorSystem, materializer));
}

根据源代码, ActorFlow创建具有flowActor名称的actor 。因此,要在代码中的某处向websockets发送消息,我们可以通过其路径找到actor 。这将向所有连接的客户端广播消息

actorSystem.actorSelection("/user/*/flowActor").tell("Hello", ActorRef.noSender());

不幸的是我没有找到改变ActorFlow默认名称的简单方法。

扫码关注云+社区

领取腾讯云代金券