2016-12-26 13 views
2

私はAkkaストリームを使用して単純なtcpサーバを構築しようとしています。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) 
    } 

私は一度に最大1つの接続を許可したいです。これを達成するために私はapplication.confファイルに次の行を追加しました。

akka.io.tcp.max-channels = 2 

この構成では、akkaは一度に1つの接続しか許可しません。しかし、とすぐに第二の接続が試行されたとして、それは要求を拒否し、次のメッセージに自身を失敗:TCPサーバがダウンしているので、

Could not register incoming connection since selector capacity limit is reached, closing connection 

この時点から、任意の接続を確立することはできません。

質問:一度に1つの接続のみを有効にする適切な方法は何ですか?主な目的は、最初の接続要求に応答し、進行中に他の接続要求を拒否することです。以前の接続が閉じられた後にもう一度接続することも可能です。私が言及したように、1つの接続だけがいつでも許可されるべきです。

BONUS:akkaストリームにこのリストからの接続のみを許可するホワイトリストを提供できますか? 私は既知のIPアドレスだけが私のサーバに接続することを許可するつもりです。これを達成するには、リクエストを拒否する適切な方法を知っていれば十分だと思います。したがって、着信接続のIPアドレスを指定されたリストと比較し、そこにない場合は拒否できます。しかし、より良い解決策もあります。

+0

処理後の接続で何をしたいですか?あなたの目標が今後の接続を拒否することだけであれば、簡単な方法では、要求の数が同時に処理されていることを示すセマフォを導入することですが、ブロックする代わりに新しい接続を拒否してください。 – maks

+0

BONUSについて:ネットワークまたはアプリケーションレベルで? – maks

+0

ストリームを扱っていませんが、ヒントはバインド後にアドレスを取得する可能性のある 'Source''Tcp.IncomingConnection'を得ることができます。その後、何らかの形でその接続を拒否することができますが、それはあなたの言葉で何が拒否されているかによって異なります。それは、着信接続にいくつかのエラーデータを書き込む別のハンドラかもしれません。 – maks

答えて

1

Tcpのバインド方法は、パラメータ「options」に「Traversable of Socket」オプションを受け入れます。あなたはそのPARAMTERに、このようになめらかに渡すことができます。

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の調査の後に結論したので、正確性をチェックしてください。

関連する問題