为什么Akka TCP流服务器在connection.handlewith没有流量时断开客户端? [英] Why does Akka TCP stream server disconnect client when there is no flow for the connection.handlewith?

查看:22
本文介绍了为什么Akka TCP流服务器在connection.handlewith没有流量时断开客户端?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找对我使用以下代码看到的行为的解释.当
conn.handleWith 被注释掉,我用 netcat 建立的 TCP 客户端连接,连接,并在几秒钟内显示被对等断开(即服务器断开连接).当代码中存在 conn.handleWith 时,我看不到断开连接.我最初认为这与为服务器设置的空闲超时有关,但事实并非如此.

I am looking for an explanation for the behavior I see with the following code. When the
conn.handleWith is commented out, the TCP client connection that I make with netcat, connects, and in a couple of seconds shows disconnected by peer (i.e. the server disconnected the connection). When the conn.handleWith is present in the code I see no disconnection. I initially though it had to do with the idletimeout set up for the server, but that wasn't the case.

那么为什么服务器在没有流量处理连接的情况下会断开客户端?

So why does the server disconnect the client when there is no flow to handle the connection?

  
    package com.example;
    
    import java.util.concurrent.CompletionStage;
    
    import akka.Done;
    import akka.NotUsed;
    import akka.actor.typed.ActorSystem;
    import akka.actor.typed.javadsl.Behaviors;
    import akka.stream.javadsl.Sink;
    import akka.stream.javadsl.Source;
    import akka.stream.javadsl.Tcp;
    import akka.stream.javadsl.Tcp.IncomingConnection;
    import akka.stream.javadsl.Tcp.ServerBinding;
    
    
    public class SimpleStream00 {
    
        public static void main(String[] args) throws InterruptedException {
    
            ActorSystem actorSystem = ActorSystem.create(Behaviors.empty(), "actorSystem");
    
            final Sink<IncomingConnection, CompletionStage<Done>> handler = Sink.foreach(conn -> {
                System.out.println("Client connected from: " + conn.remoteAddress());
                // conn.handleWith(Flow.of(ByteString.class), actorSystem); 
                // Server does not drop the connection when previous line is uncommented
            });
    
            Source<IncomingConnection, CompletionStage<ServerBinding>> source = Tcp.get(actorSystem).bind("127.0.0.1",
                    8888); // .idleTimeout(Duration.ofSeconds(60));
    
            CompletionStage<ServerBinding> bindingFuture = source.to(handler).run(actorSystem);
    
            bindingFuture.handle((binding, throwable) -> {
                if (binding != null) {
                    System.out.println("Server started, listening on: " + binding.localAddress());
    
                } else {
                    System.err.println("Server could not bind to  : " + throwable.getMessage());
                    actorSystem.terminate();
                }
                return NotUsed.getInstance();
            });
        }
    
    }

推荐答案

Akka Streams 的一般原则是,如果没有需求,流应该消耗尽可能少的资源.由于没有 handleWith,您的流永远不会从连接中发出对 ByteString 的需求信号,因此 Akka 的 TCP 层会断开连接以节省资源.

A general principle in Akka Streams is that if there's no demand, the stream should consume as few resources as possible. Since without handleWith, your stream never signals demand for the ByteStrings from the connection, Akka's TCP layer disconnects the connection to save resources.

这篇关于为什么Akka TCP流服务器在connection.handlewith没有流量时断开客户端?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆