0 votes
by (630 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
by (72.7k 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

by (630 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 ?
by (72.7k 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
by (72.7k points)
edited by

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();
        }
    }
}
...