我正在尝试使用Akka流构建一个简单的tcp服务器。
Tcp()
.bind(props.host, props.port)
.to(Sink.foreach(_.handleWith(handler)))
.run()
.onComplete {
case Success(i) => logger.info(s"Server is bound at ${props.host}:${props.port}")
case Failure(e) => logger.error("Server binding failure", e)
}
我想一次允许最多一个连接。为此,我将以下行添加到application.conf
文件中。
akka.io.tcp.max-channels = 2
使用此配置,akka一次只允许一个连接。但是,只要尝试第二次连接,它就会拒绝该请求并自行失败,并显示以下消息:
Could not register incoming connection since selector capacity limit is reached, closing connection
从这一点开始,由于Tcp服务器已关闭,因此无法建立任何连接。
问题:一次只启用一个连接的正确方法是什么?主要目的是回答第一个连接请求,并在其他请求仍在进行时拒绝其他请求。在先前的连接关闭之后,应该再次建立另一个连接。正如我所提到的,任何时候都只允许一个连接。
BONUS :是否可以提供白名单以使akka流仅接受来自此列表的连接? 我打算只允许已知的IP地址连接我的服务器。为了实现这一点,我认为知道拒绝请求的正确方法就足够了。所以我可以将传入连接的ip地址与给定列表进行比较,如果它不在那里则拒绝。但是,任何更好的解决方案也值得赞赏。
答案 0 :(得分:1)
Tcp
的绑定方法有一个参数options
,它接受一个Traversable of Socket选项。你可以将这样的smth传递给那个参数:
case class AllowedAddresses(addresses: Seq[InetAddress]) extends SocketOption {
override def beforeConnect(s: Socket): Unit = {
if (!addresses.contains(s.getInetAddress)) s.close()
}
}
因此您的代码将如下所示:
Tcp()
.bind(props.host, props.port, options = List(AllowedAddresses(listOfAddresses)))
.to(Sink.foreach(_.handleWith(handler)))
.run()
.onComplete {
case Success(i) => logger.info(s"Server is bound at ${props.host}:${props.port}")
case Failure(e) => logger.error("Server binding failure", e)
}
限制请求数量的方法是相同的,调查SocketOptions
特征中的方法
PS。没有尝试过这个,只是在调查流API之后才结束,所以请检查是否正确。