考虑到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