Search code examples
.netunity-game-enginetcpnetty

How to set DotNetty(Netty) Bootstrap.ConnectAsync timeout?


I'm using DotNetty in Unity, and has the following client bootstrap, when the server is down, it will take the "clientBootstrap.ConnectAsync()" around 17 seconds to give up trying to establish a connection, during which, the client is frozen. Actually, it doesn't need to try for 17 seconds to know there can be no connection. How can I configurate so the "clientBootstrap.ConnectAsync()" trys only for maybe 5 seconds? I added ".Option(ChannelOption.ConnectTimeout, TimeSpan.FromMilliseconds(5000))", but still, it takes 17 seconds to stop trying. The option only triggered an extra timeout exception.

    try
    {
        var clientBootstrap = new Bootstrap();
        clientBootstrap
            .Group(group)
            .Channel<TcpSocketChannel>()
            .Option(ChannelOption.TcpNodelay, true)
            .Option(ChannelOption.ConnectTimeout, TimeSpan.FromMilliseconds(1000))
            .Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
            {
                var pipeline = channel.Pipeline;
                pipeline.AddLast(new IdleStateHandler(0, 0, 6));
                ......
            }));
        clientChannel = await clientBootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(IP), Port));

Thank you very much.


Solution

  • You should be able to set a timeout according to this:

    Not familiar with dotnetty but applied to your snippet I would try something like:

    try
    {
        var clientBootstrap = new Bootstrap();
        clientBootstrap
            .Group(group)
            .Channel<TcpSocketChannel>()
            .Option(ChannelOption.TcpNodelay, true)
            .Option(ChannelOption.ConnectTimeout, TimeSpan.FromMilliseconds(1000))
            .Handler(new ActionChannelInitializer<ISocketChannel>(channel =>
            {
                var pipeline = channel.Pipeline;
                pipeline.AddLast(new IdleStateHandler(0, 0, 6));
                ......
            }));
        
        int timeout = 5000;
        var clientChannel = clientBootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(IP), Port));
        if (await Task.WhenAny(clientChannel, Task.Delay(timeout)) == clientChannel) {
            // task completed within timeout
        } else { 
            // timeout logic
        }
    }
    

    Useful to read task delay documentation: