如何使用Akka流和Akka HTTP订阅WebSocket到参与者的消息?

如何使用Akka流和Akka HTTP订阅WebSocket到参与者的消息?,akka,akka-stream,akka-http,Akka,Akka Stream,Akka Http,我想通过WebSocket向客户端发送通知。这些通知是由参与者生成的,因此我试图在服务器启动时创建参与者的消息流,并订阅WebSockets连接到此流,只发送自订阅后发出的通知 使用,我们可以创建参与者消息的源 val ref = Source.actorRef[Weather](Int.MaxValue, fail) .filter(!_.raining) .to(Sink foreach println )

我想通过WebSocket向客户端发送通知。这些通知是由参与者生成的,因此我试图在服务器启动时创建参与者的消息流,并订阅WebSockets连接到此流,只发送自订阅后发出的通知

使用,我们可以创建参与者消息的源

val ref = Source.actorRef[Weather](Int.MaxValue, fail)
                .filter(!_.raining)
                .to(Sink foreach println )
                .run()

ref ! Weather("02139", 32.0, true)
但是,如果akka http*websockets连接已经实现,我如何订阅该源的连接呢

*Akka HTTP中的WebSockets连接需要一个流[消息,消息,任意]

我想做的是

// at server startup
val notifications: Source[Notification,ActorRef] = Source.actorRef[Notificacion](5,OverflowStrategy.fail)
val ref = notifications.to(Sink.foreach(println(_))).run()
val notificationActor = system.actorOf(NotificationActor.props(ref))

// on ws connection
val notificationsWS = path("notificationsWS") {
  parameter('name) { name ⇒
    get {
      onComplete(flow(name)){
        case Success(f) => handleWebSocketMessages(f)
        case Failure(e) => throw e
      }
    }
  }
}

def flow(name: String) = {
  val messages = notifications filter { n => n.name equals name } map { n => TextMessage.Strict(n.data) }
  Flow.fromSinkAndSource(Sink.ignore, notifications)
}
这不起作用,因为通知源不是具体化的源,因此它不发出任何元素

注意:我使用的是Source.actorPublisher,它正在工作,但ktoso和我也遇到了以下错误:

java.lang.IllegalStateException: onNext is not allowed when the stream has not requested elements, totalDemand was 0.

您可以使用mapMaterializedValue将具体化的actorRef公开给某些外部路由器参与者

路由器可以跟踪你的消息来源,actorrefs deathwatch可以帮助整理信息并将消息转发给他们

注意:您可能已经意识到了,但是请注意,通过使用Source.actorRef为您的流提供反馈,您的流不会意识到您选择的策略的背压,它只会在负载下崩溃

Flow.fromSinkAndSourceMat(Sink.ignore, notifications)(Keep.right)
  .mapMaterializedValue(srcRef => router ! srcRef)