2012-08-13 24 views
7

Mam serwer datasnap z klientem formularzy vcl. Od klienta, w jaki sposób mogę obsłużyć, jeśli serwer został powiedziany zamknięcie i ponownie uruchomiony z istniejących połączeń klienta? Ten scenariusz wywołuje wyjątek 10053 EIdSocketError.Datasnap i SocketError

Aby zreplikować, uruchamiam zarówno serwer, jak i klienta, wykonuję połączenie z serwerem (korzystam z metod ujawnianych przez generator proxy DataSnap), który działa pomyślnie. Następnie wyłączam serwer (np. Zamknij aplikację) i uruchom go ponownie. Próbuję ponownie nawiązać połączenie z serwerem.

np KLIENT wezwanie

sm := TsvrPolicySearchClient.Create(datClientDB.SQLConnection1.DBXConnection); 
    try 
     ds := sm.SearchPolicyByPolicy(40, WCRef, '', 3); 
     dspPolicyGroup.DataSet := ds; 

     if cdsPolicyGroup.Active then 
     cdsPolicyGroup.Refresh 
     else 
     cdsPolicyGroup.Open; 

    finally 
     sm.Free; 
    end; 

dspPolicyGroup jest TDataSetProvider i cdsPolicyGroup jest TClientDataSet (ja po prostu używać go lokalnie do "sklepu" mój wynik TDataSet).

SERWER

function TsvrPolicySearch.SearchPolicyByPolicy(AClientId: Integer; WCRefNum, ClientRef: string; SearchMethod: Integer): TDataSet; 
begin 
    spPolicyByWCRef.Close; 
    spPolicyByWCRef.ParamByName('p_client').AsInteger := AClientId; 
    spPolicyByWCRef.ParamByName('p_search_method').AsInteger := SearchMethod; 
    spPolicyByWCRef.ParamByName('p_wc_refno').AsString := WCRefNum; 
    spPolicyByWCRef.Open; 
    Result := spPolicyByWCRef; 
end; 

Myślę ten jest regularnie napotykanych przez ludzi widząc, że jest to dość łatwe do powtórzenia. Czy przed każdym wywołaniem powinienem wykonać połączenie "Połączenie testowe" lub coś takiego (takie jak metoda TestConnection), aby sprawdzić EIdSocketError (i odpowiednik) i obsłużyć? A może jest to raczej wada projektowa?

Dzięki

Odpowiedz

1

Najprostszym obejście tego problemu jest zmiana atrybutu TDSServerClass Lifecycle do wywołania. Spowoduje to utworzenie serwera bezstanowego, a serwer utworzy nową sesję dla każdego żądania. Ale będziesz w stanie zamknąć i ponownie połączyć serwer bez przerywania połączenia z klientami.

2

Mój scenariusz:

  • Aplikacja kliencka połączyć się z serwerem DataSnap (TCP/IP, serwer zdalny)
  • życzenie klienta zbiorze danych (z wykorzystaniem metod serwera DataSnap). TClientDataSet
  • Client pobrać zestaw danych
  • Server shutdown (taskkill, blisko zgłoszenie nr sprawy)
  • życzenie klienta DataSet againt (ehhrrr Socket Error)

Rozwiązanie:

  • Na klienckim I wyjątek przechwytywania (AppEvents.OnException)
  • Rozpoznanie, że jest błąd gniazda z połączenia z serwerem DataSnap
  • Wyświetlam okno dialogowe z informacją, że połączenie zostało utracone. Użytkownik może kliknąć przycisk „Ponów” - jeśli tak,
    • Wolne i ponownie utworzyć moduł kliencki DataSnap i zainicjować POŁĄCZENIE
    • Spróbuj żądania zestawu danych (specjalny zestaw danych dla testu połączenia) jeżeli wyjątek haczyk aplikacja cały proces działa od początku.

Po tej operacji mój klient ponownie połączyć się z serwerem DataSnap i może zażądać zestawu danych za pomocą nowego połączenia TCP/IP. Oczywiście użytkownik może zamknąć okno dialogowe, ale aplikacja jest wyłączona.

Myślę, że to może ci pomóc. Próbowałem wielu innych rozwiązań, ale okazało się to najlepsze. Ponadto algorytm obsługuje również utratę połączenia z winą klienta.