我试图通过戳this来了解akka演员代码中的akka-streams'结构。
在我的实验中遇到的问题我想知道他们的原因和方法。我用asterix和一个数字指向代码:
我使用了“限制”策略来限制传入的消息但是当流关闭时它仍会导致延迟,所以我想避免这种延迟然后试图阻止使用 1 和 6 进行流程但我不知道如何在 2 中使用限制器。也许你可以帮助我?
你可以在 4 中看到我可以访问websocket的内部actor,我可以通过将它传递给我的ChatRoomActor来区分actor,但我需要有actor在 5 中退出的时间,所以我可以在上下文中找到退出者!
class ChatRoom(chatRoomActor: ActorRef, actorSystem: ActorSystem) extends ChatRoomTrait {
def websocketFlow(user_id: String): Flow[Message, Message, Any] =
Flow.fromGraph(
GraphDSL.create(Source.actorRef[ChatMessage](bufferSize = 1000, OverflowStrategy.fail)) {
implicit builder =>
chatSource =>
import GraphDSL.Implicits._
implicit val executionContext = actorSystem.dispatcher
var stopper = builder.add(KillSwitches.single[ChatEvent]) // ****1
val fromWebsocket = builder.add(
Flow[Message]
.watchTermination()(
(_, te) => te.onSuccess {
case cause => // ****2
})
.throttle(1, 1 seconds, 1, ThrottleMode.shaping) // ****3
//.buffer(1, OverflowStrategy.backpressure)
//.delay(1 seconds, DelayOverflowStrategy.backpressure)
.collect {
case TextMessage.Strict(txt) => IncomingMessage(user_id, txt)
}
)
val actorAsSource = builder.materializedValue.map(actor => UserJoined(user_id+, actor)) // ****4
val chatActorSink = Sink.actorRef[ChatEvent](chatRoomActor, UserLeft(user_id)) // ****5
val mergeToChat = builder.add(Merge[ChatEvent](2))
actorAsSource ~> mergeToChat.in(0)
fromWebsocket ~> mergeToChat.in(1)
mergeToChat ~> stopper ~> chatActorSink //****6
val backToWebsocket = builder.add(
Flow[ChatMessage].groupedWithin(10, 300 millis).mapConcat {
msgs => msgs map {
case ChatMessage(author, text) => TextMessage(s"[$author]: $text")
}
}
)
chatSource ~> backToWebsocket
FlowShape(fromWebsocket.in, backToWebsocket.out)
}
)}