如何将同一源流式传输到一个或多个HTTP服务器和WebSocket?

时间:2019-01-14 23:01:54

标签: akka-stream akka-http

考虑到ByteString的来源,我需要将流转发到一个或多个akka-http服务器,并将每个ByteString写入一个或多个WebSockets。

我尝试使用图广播ByteString,但这导致对每个ByteString进行HTTP推送,而不是将它们流式传输到服务器。

我还尝试使用BroadcastHub.sink获取可用于创建流HttpRequest的可重用源。可行,但是在某些情况下,似乎在读取数据之前清空或完成了源代码。如果有更快的本地WebSocket消耗数据,则远程HTTP服务器的结尾为0或字节太少。

关于如何可靠地执行此操作的任何建议?

例如,这是使用BroadcastHub.sink的部分代码:

val runnableGraph  = source.toMat(BroadcastHub.sink(bufferSize = 1))(Keep.right)
val reusableSource = runnableGraph.run()

def sendToRemoteServer(h: ServerInfo) = {
  Source
    .single(makeHttpRequest(streamName, h, reusableSource))
    .via(remoteConnections(h))
    .runWith(Sink.ignore)
}

val remoteSetF = remoteHostSet.map(sendToRemoteServer)

def sendToLocalWebSocket(a: AccessInfo) = {
  reusableSource
    .alsoTo(localSubscribers(a).sink)
    .mapAsync(1) { bs =>
      waitForAck(a).map(_ => ByteString.empty)
    }
    .runWith(Sink.ignore)
}

val localSetF = localSet.map(sendToLocalWebSocket)

Future.sequence(localSetF ++ remoteSetF).map(_ => Done)

我尝试过的另一种解决方案是使用图形,但是为了将数据流传输到HTTP服务器,我需要在创建HttpRequest时传递一个Source,而我在图形中没有该信息:

  // Create the graph
  source ~> bcast
  localFlows.foreach(bcast ~> _ ~> merge)
  remoteFlows.foreach(bcast ~> _ ~> merge)
  merge ~> out
  ClosedShape

0 个答案:

没有答案