Есть ли способ отключить IdleState? - PullRequest
0 голосов
/ 16 февраля 2019

Я настраиваю сервер DotNetty.Мой первый обработчик - IdleStateHandler.Есть ли способ отключить этот обработчик при получении данных, а затем включить его после WriteAndFlushAsync?

public class TimeoutHandler :IdleStateHandler
{
    private bool enable = true;

    protected override void ChannelIdle(IChannelHandlerContext context, IdleStateEvent stateEvent)
    {        
         base.ChannelIdle(context, stateEvent);
    }

    public override void ChannelRead(IChannelHandlerContext context, object message)
    {
        Console.WriteLine(IdleState.ReaderIdle);

        NewIdleStateEvent(IdleState.ReaderIdle, false);

        base.ChannelRead(context, message);
    }

    public override Task WriteAsync(IChannelHandlerContext context, object message)
    {                                             
        return context.WriteAndFlushAsync(message as IByteBuffer); 
    }


    public TimeoutHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) : base(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds)
    {

    }

    public TimeoutHandler(TimeSpan readerIdleTime, TimeSpan writerIdleTime, TimeSpan allIdleTime) : base(readerIdleTime, writerIdleTime, allIdleTime)
    {
    }

    public TimeoutHandler(bool observeOutput, TimeSpan readerIdleTime, TimeSpan writerIdleTime, TimeSpan allIdleTime) : base(observeOutput, readerIdleTime, writerIdleTime, allIdleTime)
    {
    }
}

1 Ответ

0 голосов
/ 16 февраля 2019

Обработчик сделает это за вас.Если вы наследуете от IdleStateHandler, все, что вам действительно нужно сделать, - это реализовать один или несколько его конструкторов и переопределить ChannelIdle.Вот простой пример, который закрывает соединение после определенного периода бездействия;он автоматически сбрасывается при наличии активности:

public class TimeoutHandler : IdleStateHandler
{
    /// <summary>
    /// Initializes a new instance firing <see cref="T:DotNetty.Handlers.Timeout.IdleStateEvent" />s.
    /// </summary>
    /// <param name="readerIdleTimeSeconds">
    ///     an <see cref="T:DotNetty.Handlers.Timeout.IdleStateEvent" /> whose state is <see cref="F:DotNetty.Handlers.Timeout.IdleState.ReaderIdle" />
    ///     will be triggered when no read was performed for the specified
    ///     period of time.  Specify <code>0</code> to disable.
    /// </param>
    /// <param name="writerIdleTimeSeconds">
    ///     an <see cref="T:DotNetty.Handlers.Timeout.IdleStateEvent" /> whose state is <see cref="F:DotNetty.Handlers.Timeout.IdleState.WriterIdle" />
    ///     will be triggered when no write was performed for the specified
    ///     period of time.  Specify <code>0</code> to disable.
    /// </param>
    /// <param name="allIdleTimeSeconds">
    ///     an <see cref="T:DotNetty.Handlers.Timeout.IdleStateEvent" /> whose state is <see cref="F:DotNetty.Handlers.Timeout.IdleState.AllIdle" />
    ///     will be triggered when neither read nor write was performed for
    ///     the specified period of time.  Specify <code>0</code> to disable.
    /// </param>
    public TimeoutHandler(int readerIdleTimeSeconds, int writerIdleTimeSeconds, int allIdleTimeSeconds) : base(readerIdleTimeSeconds, writerIdleTimeSeconds, allIdleTimeSeconds)
    {
    }

    protected override void ChannelIdle(IChannelHandlerContext context, IdleStateEvent stateEvent)
    {
        context.CloseAsync();
    }
}

Чтобы добавить его в конвейер с периодом бездействия 60 секунд (для любой тип бездействия):

pipeline.AddLast(name: "idle-handler", new
   TimeoutHandler(readerIdleTimeSeconds: 60, writerIdleTimeSeconds: 60, allIdleTimeSeconds: 60));

Стоит посмотреть на исходный код для DotNetty IdleStateHandler (учитывая отсутствие документации).Например, вы увидите, что в WriteAsync по завершении задачи записи сбрасывается lastWriteTime.

...