WebClient po jakimś czasie traci połączenie podczas dużego pliku po FTP

0

Witam!
Walczę już sporo czasu z tym przypadkiem i może ktoś tutaj będzie wiedział co mam z tym zrobić. Tak jak już w poprzednim poście pisałem, mam apkę do robienia kopii zapasowych baz danych MSSQL, które po zapakowaniu wysyłam na chmurę. Znalazł się taki JEDEN przypadek, który ma problem z wysyłaniem po jakimś czasie. W związku z tym, że net u tego człowieka nie należy do super szybkich, trochę to trwa zanim się wysypie.

  1. Ustawiłem timer na 20:20
  2. O 20:25 miałem już zapakowany plik (1.75GB), wysyła
  3. 21:57 - Exception
FUNCTION: UploadFile 
MESSAGE: Połączenie podstawowe zostało zakończone: Wystąpił nieoczekiwany błąd przy odbiorze. 
SOURCE System 
HRESULT: -2146233079 
STACKTRACE:    
   w System.Net.WebClient.UploadFile(Uri address, String method, String fileName)
   w System.Net.WebClient.UploadFile(String address, String fileName)
   w OptimoBackup.Classes.FTP.UploadFile(MainBackup ftp, String fileName, String path)
   w OptimoBackup.Classes.BackupTask.HandleConditionsMetEvent(Object sender, ConditionsMetEventArgs e) 

Z początku myślałem, że antywirus (ESET) ale wyłączony był tym razem i dalej nic.
Zrobiłem sobie klasę, aby pomanewrować timeoutem bo z tym też miałem problem właśnie u tego samego człowieka

    public class NoKeepAliveWebClient : WebClient
    {
        protected override WebRequest GetWebRequest(Uri address)
        {
            var request = base.GetWebRequest(address);
            if (request is HttpWebRequest)
            {
                ((HttpWebRequest)request).KeepAlive = false;
                ((HttpWebRequest)request).Timeout = System.Threading.Timeout.Infinite;
            }

            return request;
        }
    }

I wysyłam tak:

        public static void UploadFile(MainBackup ftp, string fileName, string path)
        {
            string uploadPath = Host + "u"+ftp.NIP+"/" + fileName;
            string fileDir = path + fileName;

            using (var webClient = new NoKeepAliveWebClient())
            {
                webClient.Credentials = new NetworkCredential(User, Password);
                webClient.UploadFile(uploadPath, fileDir);
            }
        }

Co najciekawsze, mam jedną firmę, której zapakowana baza ma ponad 2GB i nie ma z tym żadnego problemu. W sumie mam około 20 takich firm (z mniejszymi bazami) i żaden nie wali takim wyjątkiem. Próbowałem manewrować godzinami, zaporą, antywirusem, sprawdzałem neta i żadnego punktu zaczepienia.
Ktoś? Coś?

2

Abstrahując kompletnie od tego przypadku, sieć jest zawodna, zamiast wysyłać cały plik za jednym razem ja bym go podzielił na małe kawałki (<100MB) i retransmitował w przypadku porażki któregoś z kawałków tylko jego + do tego Exponential backoff.

0

Zawsze to jakieś rozwiązanie. Można dodać opcję pakowania w częściach w takich przypadkach jak ten ale nie chcesz mi powiedzieć, że to jest jedyne rozwiązanie?

1

Na podobnej zasadzie działają programy do pobierania danych. Ustalają sobie jakiś bufor i zapisują. Jak coś się schrzani, to rozpoczynają od konkretnego miejsca. Ty zrobisz to samo. Ustalisz sobie bufor (część pliku o konkretnym rozmiarze) i wyślesz. Jak coś się spieprzy, to wysyłasz od ostatniej części. Możesz próbować różnych dziwnych sztuczek i manewrów, ale to będzie najprostsze i będzie działać dobrze. Wszystkie inne rozwiązania, jakie można by wymyślić, to jakieś wyje***tne mechanizmy, które i tak mogą być zawodne. Generalnie przerost formy nad treścią.

0

Nie ma sensu pisać tego samemu. Zamie WebClient na FtpClient korzystając z FluentFtp na nugecie. Przetestowane i kontynuuje automatycznie przerwane połączenie na podstawie ftpClient.RetryAttempts
Dzięki za pomoc.

0

@neves: mówisz o dzieleniu pliku na kawałki przed wysłaniem. A co je scali na serwerze ftp? Bo jak wysle coś w np 10 kawałkach to na serwerze FTP bede miał 10 plików

0
Mistrzowski Orzeł napisał(a):

@neves: mówisz o dzieleniu pliku na kawałki przed wysłaniem. A co je scali na serwerze ftp? Bo jak wysle coś w np 10 kawałkach to na serwerze FTP bede miał 10 plików

Tutaj musisz zrobić już coś nieco innego. W zależności co tak naprawdę robisz.

  • Jakieś WebAPI, które Ci to wszystko ogarnia
  • jakiś plik konfiguracyjny - np. klient, który chce pobrać wszystkie fragmenty, pobiera najpierw plik konfiguracyjny i tam ma już wszystko napisane co ma pobierać i co to jest
  • wrzucasz wszystkie części do jakiegoś folderu i klient bierze wszystkie części z tego folderu i składa sobie na pałę.

1 użytkowników online, w tym zalogowanych: 0, gości: 1