允许与Akka流单个连接作为tcp服务器

时间:2016-12-26 13:54:08

标签: scala tcp server akka akka-stream

我正在尝试使用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地址与给定列表进行比较,如果它不在那里则拒绝。但是,任何更好的解决方案也值得赞赏。

1 个答案:

答案 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之后才结束,所以请检查是否正确。