我们正在:akka-stream-experimental_2.11 1.0。
的启发我们写了一个TCP接收器如下:
def bind(address: String, port: Int, target: ActorRef)
(implicit system: ActorSystem, actorMaterializer: ActorMaterializer): Future[ServerBinding] = {
val sink = Sink.foreach[Tcp.IncomingConnection] { conn =>
val serverFlow = Flow[ByteString]
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256, allowTruncation = true))
.map(message => {
target ? new Message(message); ByteString.empty
})
conn handleWith serverFlow
}
val connections = Tcp().bind(address, port)
connections.to(sink).run()
}
但是,我们的目的是让接收器完全不响应并且只接收消息。 (TCP消息发布者不关心响应)。
甚至可能吗?因为akka.stream.scaladsl.Tcp.IncomingConnection采用以下类型的流来完全不响应:Flow [ByteString,ByteString,Unit]
如果是,将非常感谢一些指导。提前谢谢。
以下一次尝试通过我的单元测试,但不确定它是否是最好的主意:
def bind(address: String, port: Int, target: ActorRef)
(implicit system: ActorSystem, actorMaterializer: ActorMaterializer): Future[ServerBinding] = {
val sink = Sink.foreach[Tcp.IncomingConnection] { conn =>
val targetSubscriber = ActorSubscriber[Message](system.actorOf(Props(new TargetSubscriber(target))))
val targetSink = Flow[ByteString]
.via(Framing.delimiter(ByteString("\n"), maximumFrameLength = 256, allowTruncation = true))
.map(Message(_))
.to(Sink(targetSubscriber))
conn.flow.to(targetSink).runWith(Source(Promise().future))
}
val connections = Tcp().bind(address, port)
connections.to(sink).run()
}
答案 0 :(得分:1)
你走在正确的轨道上。为了在某些时候保持关闭连接的可能性,您可能希望保留承诺并在以后完成它。一旦元素完成,该元素由源发布。但是,由于您不希望在连接上发布任何元素,因此您可以使用drop(1)
确保源永远不会发出任何元素。
这是您的示例的更新版本(未经测试):
val promise = Promise[ByteString]()
// this source will complete when the promise is fulfilled
// or it will complete with an error if the promise is completed with an error
val completionSource = Source(promise.future).drop(1)
completionSource // only used to complete later
.via(conn.flow) // I reordered the flow for better readability (arguably)
.runWith(targetSink)
// to close the connection later complete the promise:
def closeConnection() = promise.success(ByteString.empty) // dummy element, will be dropped
// alternatively to fail the connection later, complete with an error
def failConnection() = promise.failure(new RuntimeException)