SFTP state change event

0 votes
asked May 28 by Prabhakar (470 points)

After SFTP client connects to SFTP server, when the server goes offline will Sftp::StateChanged Event get fired? From SftpStateChangedEventArgs::NewState, I would be able to get the Disconnected enum value?

Applies to: Rebex SFTP

2 Answers

0 votes
answered May 28 by Lukas Matyska (54,470 points)

No, when the SFTP server goes offline, no event is fired on SFTP client.

To fire the event, you have to perform some operation actively. You can use for example the KeepAlive() method.

If you will call this method in cycle (when the client is idle), you will:
1. keep the SFTP connection alive
2. be notified about server disconnection

commented May 29 by Prabhakar (470 points)
I can have implementation similar to link below.
http://forum.rebex.net/3484/sshsession-keepalive-method
I would then be notified with Sftp::StateChanged Event ?
commented May 29 by Lukas Matyska (54,470 points)
I have updated the SftpKeepAlive class to address your needs. Please, see my second answer http://forum.rebex.net/10269/sftp-state-change-event?show=10278#a10278
0 votes
answered May 29 by Lukas Matyska (54,470 points)
edited Jul 1 by Lukas Pokorny

Apparently, the KeepAlive() method does not change the State property. This is a bug and we will fix this in a future version has been fixed in Rebex SFTP 2019 R3.

I have updated the SftpKeepAlive sample class to workaround this issue.

public class SftpKeepAlive : Sftp
{
    // Timer object (needs to be referenced to prevent it from being
    // claimed by the garbage collector).
    private readonly System.Threading.Timer _keepAliveTimer;

    public SftpKeepAlive()
    {
        // initialize the timer
        var oneMinute = TimeSpan.FromSeconds(60);
        _keepAliveTimer = new System.Threading.Timer(KeepAliveCallback, null, oneMinute, oneMinute);
    }

    private void KeepAliveCallback(object state)
    {
        try
        {
            if (State == SftpState.Ready)
            {
                // send keep-alive packet to the server
                Session.KeepAlive();
            }
        }
        catch (Exception ex)
        {
            // log the exception here
            // ...

            if (State == SftpState.Ready)
            {
                // KeepAlive() do not change State currently, raise event manually
                OnStateChanged(new SftpStateChangedEventArgs(State, SftpState.Disconnected));
            }
        }
    }

    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        if (disposing)
        {
            // dispose the timer
            _keepAliveTimer.Dispose();
        }
    }
}
...