开:akka-stream-experimental_2.11 1.0。
我们在Tcp服务器中使用Framing.delimiter。当消息到达时,其长度大于maximumFrameLength,抛出FramingException,我们可以从ActorSubscriber的OnError中捕获它。
服务器代码:
def bind(address: String, port: Int, target: ActorRef, maxInFlight: Int, maxFrameLength: Int)
(implicit system: ActorSystem, actorMaterializer: ActorMaterializer): Future[ServerBinding] = {
val sink = Sink.foreach {
conn: Tcp.IncomingConnection =>
val targetSubscriber = ActorSubscriber[Message](system.actorOf(Props(new TargetSubscriber(target, maxInFlight))))
val targetSink = Flow[ByteString]
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = maxFrameLength, allowTruncation = true))
.map(raw ⇒ Message(raw))
.to(Sink(targetSubscriber))
conn.flow.to(targetSink).runWith(Source(Promise().future))
}
val connections = Tcp().bind(address, port)
connections.to(sink).run()
}
订阅者代码:
class TargetSubscriber(target: ActorRef, maxInFlight: Int) extends ActorSubscriber with ActorLogging {
private var inFlight = 0
override protected def requestStrategy = new MaxInFlightRequestStrategy(maxInFlight) {
override def inFlightInternally = inFlight
}
override def receive = {
case OnNext(msg: Message) ⇒
target ! msg
inFlight += 1
case OnError(t) ⇒
inFlight -= 1
log.error(t, "Subscriber encountered error")
case TargetAck(_) ⇒
inFlight -= 1
}
}
问题: 对于该传入连接,此最大帧长度以下的消息不会流动。杀死客户端并重新运行它可以正常工作。
ActorSubscriber不尊重supervision
跳过错误信息并继续下一条好消息的正确方法是什么?
答案 0 :(得分:0)
您是否尝试过监督targetFlow
接收器而不是整个物质供应商?我在这里看不到它,我相信它应该直接设置在那个流程上。
这比科学;)
更令人猜测答案 1 :(得分:-1)
我在读取文件时遇到了同样的异常,对我来说,通过在最后一行之后放置一个返回来解决这个问题。